From 066a5ea5dc7856cfd765b5695eba073b05fc2438 Mon Sep 17 00:00:00 2001 From: volodya-lombrozo Date: Sat, 2 Nov 2024 12:56:08 +0300 Subject: [PATCH] feat(#750): add one more unit test for frames computation --- .../bytecode/BytecodeMethod.java | 20 ++++++ .../bytecode/BytecodeMethodTest.java | 63 +++++++++++++++---- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java index 2fe7eb49b..3b009edb1 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import lombok.EqualsAndHashCode; @@ -361,6 +362,25 @@ BytecodeMaxs currentMaxs() { return this.maxs; } + /** + * Compute frames. + * @return Frames. + */ + List computeFrames() { + return Collections.emptyList(); + } + + /** + * Current frames. + * @return Frames. + */ + List currentFrames() { + return this.instructions.stream() + .filter(BytecodeFrame.class::isInstance) + .map(BytecodeFrame.class::cast) + .collect(Collectors.toList()); + } + /** * Add instruction. * @param opcode Opcode. diff --git a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java index ff7f09af6..557620944 100644 --- a/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java +++ b/src/test/java/org/eolang/jeo/representation/bytecode/BytecodeMethodTest.java @@ -26,6 +26,7 @@ import com.jcabi.matchers.XhtmlMatchers; import com.jcabi.xml.XMLDocument; import it.JavaSourceClass; +import java.util.List; import java.util.UUID; import java.util.stream.Stream; import org.cactoos.bytes.BytesOf; @@ -462,7 +463,7 @@ void visitsTableSwitchInstructionSuccessfully() throws ImpossibleModificationExc } @ParameterizedTest(name = "Computing maxs for method {1}, expected {2}") - @MethodSource("implementedMethods") + @MethodSource("implementedMaxs") void computesMaxsCorrectlyForImplementedMethods( final BytecodeMethod method, final String name, @@ -479,7 +480,7 @@ void computesMaxsCorrectlyForImplementedMethods( } @ParameterizedTest(name = "Computing maxs for method {1}, expected {2}") - @MethodSource("abstractMethods") + @MethodSource("abstractMaxs") void computesMaxsCorrectlyForAbstractMethods( final BytecodeMethod method, final String name, @@ -496,7 +497,7 @@ void computesMaxsCorrectlyForAbstractMethods( } @ParameterizedTest(name = "Computing maxs for method {1}, expected {2}") - @MethodSource("realMethods") + @MethodSource("realMaxs") void computesMaxForRealClassAfterAllTransformations( final BytecodeMethod method, final String name, @@ -513,6 +514,33 @@ void computesMaxForRealClassAfterAllTransformations( ); } + @ParameterizedTest + @MethodSource("implementedFrames") + void computesStackMapFramesForSomeMethods( + final BytecodeMethod method, + final String name, + final List expected + ) { + MatcherAssert.assertThat( + String.format( + "Stack map frames weren't computed correctly for method %s", + name + ), + method.computeFrames(), + Matchers.equalTo(expected) + ); + } + + /** + * Provides implemented methods for testing. + * These methods contain different stack map frames. + * Used in {@link #computesStackMapFramesForSomeMethods(BytecodeMethod, String, List)}. + * @return Stream of argumentsForTesting(). + */ + static Stream implementedFrames() { + return BytecodeMethodTest.methodFrames("maxs/Maxs.java"); + } + /** * Provides implemented methods for testing. * These methods contain different number of local variables and stack elements. @@ -520,8 +548,8 @@ void computesMaxForRealClassAfterAllTransformations( * {@link #computesMaxsCorrectlyForImplementedMethods(BytecodeMethod, String, BytecodeMaxs)}. * @return Stream of arguments. */ - static Stream implementedMethods() { - return BytecodeMethodTest.methods("maxs/Maxs.java"); + static Stream implementedMaxs() { + return BytecodeMethodTest.methodMaxs("maxs/Maxs.java"); } /** @@ -531,8 +559,8 @@ static Stream implementedMethods() { * {@link #computesMaxsCorrectlyForImplementedMethods(BytecodeMethod, String, BytecodeMaxs)}. * @return Stream of arguments. */ - static Stream abstractMethods() { - return BytecodeMethodTest.methods("maxs/MaxInterface.java"); + static Stream abstractMaxs() { + return BytecodeMethodTest.methodMaxs("maxs/MaxInterface.java"); } /** @@ -540,12 +568,12 @@ static Stream abstractMethods() { * Before that, we disassemble and assemble the compiled class. * @return Stream of arguments. */ - static Stream realMethods() { + static Stream realMaxs() { return Stream.of( "AbstractEndpoint.class", "FastHttpDateFormat.class", "ByteArrayClassLoader$ChildFirst$PrependingEnumeration.class" - ).flatMap(BytecodeMethodTest::disassembleAssemble); + ).flatMap(BytecodeMethodTest::realMaxs); } /** @@ -555,7 +583,7 @@ static Stream realMethods() { * @checkstyle IllegalCatchCheck (25 lines) */ @SuppressWarnings("PMD.AvoidCatchingGenericException") - static Stream disassembleAssemble(final String compiled) { + static Stream realMaxs(final String compiled) { try { return new XmlProgram( new BytecodeRepresentation( @@ -581,11 +609,24 @@ static Stream disassembleAssemble(final String compiled) { * @param clazz Resource class name. * @return Stream of arguments. */ - static Stream methods(final String clazz) { + static Stream methodMaxs(final String clazz) { return new AsmProgram( new JavaSourceClass(clazz).compile().bytes() ).bytecode().top().methods().stream().map( method -> Arguments.of(method, method.name(), method.currentMaxs()) ); } + + /** + * Provides method frames for testing. + * @param clazz Resource class name. + * @return Stream of arguments. + */ + static Stream methodFrames(final String clazz) { + return new AsmProgram( + new JavaSourceClass(clazz).compile().bytes() + ).bytecode().top().methods().stream().map( + method -> Arguments.of(method, method.name(), method.currentFrames()) + ); + } }