diff options
author | Sven Gothel <[email protected]> | 2014-09-24 01:08:38 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-09-24 01:08:38 +0200 |
commit | 616f566cfe60638eb97823e1f63cf203161502da (patch) | |
tree | 01dbf7117632cfae1584376b1f44c6e931953f95 /api/src/test | |
parent | ad4cc1c77559a6d0138acd320cb1dfd638a0f86f (diff) |
Fix jardiff's Tools.isAccessChange(..): Differentiate between Class, Field and Method and apply all rules of the Java Language Specification
Class, Field and Methods have different binary backward compatibility rules
as specified in the Java Language Specification, Java SE 7 Edition:
- http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html
For Field 'volatile' the Java Language Specification, first edition has been used:
- http://www.wsu.edu/UNIX_Systems/java/langspec-1.0/13.doc.html#45194
For each type separate method have been created, i.e. Tools.is<Type>AccessChange().
Each new method has the rules referenced and partially copied into the method
for better documentation.
The now deprecated method Tools.isAccessChange(..) calls Tools.isClassAccessChange(..)
and shall be removed.
Unit test ToolsTest has been expanded for each type and its rules.
Diffstat (limited to 'api/src/test')
-rw-r--r-- | api/src/test/java/org/osjava/jardiff/ToolsTest.java | 120 |
1 files changed, 105 insertions, 15 deletions
diff --git a/api/src/test/java/org/osjava/jardiff/ToolsTest.java b/api/src/test/java/org/osjava/jardiff/ToolsTest.java index 148543a..39683bd 100644 --- a/api/src/test/java/org/osjava/jardiff/ToolsTest.java +++ b/api/src/test/java/org/osjava/jardiff/ToolsTest.java @@ -22,26 +22,116 @@ import static org.junit.Assert.*; public class ToolsTest { + static class lala { + int lala; + } + @Test - public void isAccessChange() { - // A class or method or field can't become final. - assertTrue(Tools.isAccessChange(0, Opcodes.ACC_FINAL)); - assertTrue(Tools.isAccessChange(0, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); + public void isClassAccessChange() { + // A class can't become final. + assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_FINAL)); + assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); // ... but can become non-final. - assertFalse(Tools.isAccessChange(Opcodes.ACC_FINAL, 0)); - assertFalse(Tools.isAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + assertFalse(Tools.isClassAccessChange(Opcodes.ACC_FINAL, 0)); + assertFalse(Tools.isClassAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + // No matter the final access, can't become protected or private or // package if it was public. - assertTrue(Tools.isAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, 0)); - assertTrue(Tools.isAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED)); - // A class or method can become concrete. - assertFalse(Tools.isAccessChange(Opcodes.ACC_ABSTRACT, 0)); - assertFalse(Tools.isAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); - assertFalse(Tools.isAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED)); + assertTrue(Tools.isClassAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, 0)); + assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED)); + // A class can become concrete. + assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT, 0)); + assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + assertFalse(Tools.isClassAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED)); // ...but can't become abstract - assertTrue(Tools.isAccessChange(0, Opcodes.ACC_ABSTRACT)); - assertTrue(Tools.isAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT)); - assertTrue(Tools.isAccessChange(Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED + Opcodes.ACC_ABSTRACT)); + assertTrue(Tools.isClassAccessChange(0, Opcodes.ACC_ABSTRACT)); + assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT)); + assertTrue(Tools.isClassAccessChange(Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED + Opcodes.ACC_ABSTRACT)); } + @Test + public void isFieldAccessChange() { + // A field can't become final. + assertTrue(Tools.isFieldAccessChange(0, Opcodes.ACC_FINAL)); + assertTrue(Tools.isFieldAccessChange(0, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); + // ... but can become non-final. + assertFalse(Tools.isFieldAccessChange(Opcodes.ACC_FINAL, 0)); + assertFalse(Tools.isFieldAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + + // No matter the final access, can't become protected or private or + // package if it was public. + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, 0)); + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED)); + + // A field can't change static + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_STATIC, 0)); + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + + // A field can't change volatile + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_VOLATILE, 0)); + assertTrue(Tools.isFieldAccessChange(Opcodes.ACC_VOLATILE + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + + // A field can change transient + assertFalse(Tools.isFieldAccessChange(0, + Opcodes.ACC_TRANSIENT)); + assertFalse(Tools.isFieldAccessChange(Opcodes.ACC_PUBLIC, + Opcodes.ACC_PUBLIC + Opcodes.ACC_TRANSIENT)); + assertFalse(Tools.isFieldAccessChange(Opcodes.ACC_TRANSIENT, + 0)); + assertFalse(Tools.isFieldAccessChange(Opcodes.ACC_PUBLIC + Opcodes.ACC_TRANSIENT, + Opcodes.ACC_PUBLIC)); + } + + @Test + public void isMethodAccessChange() { + // A non-static method can't become final. + assertTrue(Tools.isMethodAccessChange(0, Opcodes.ACC_FINAL)); + assertTrue(Tools.isMethodAccessChange(0, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); + // ... but can become non-final. + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_FINAL, 0)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + // ... but a static method can become final! + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_STATIC, + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC, + Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL)); + + // No matter the final access, can't become protected or private or + // package if it was public. + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_FINAL + Opcodes.ACC_PUBLIC, 0)); + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED)); + // A class or method can become concrete. + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_ABSTRACT, 0)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_ABSTRACT + Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED)); + // ...but can't become abstract + assertTrue(Tools.isMethodAccessChange(0, Opcodes.ACC_ABSTRACT)); + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT)); + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_PROTECTED, Opcodes.ACC_PROTECTED + Opcodes.ACC_ABSTRACT)); + + // A method can't change static + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_STATIC, 0)); + assertTrue(Tools.isMethodAccessChange(Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC, Opcodes.ACC_PUBLIC)); + + // A method can change synchronized + assertFalse(Tools.isMethodAccessChange(0, + Opcodes.ACC_SYNCHRONIZED)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC, + Opcodes.ACC_PUBLIC + Opcodes.ACC_SYNCHRONIZED)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_SYNCHRONIZED, + 0)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC + Opcodes.ACC_SYNCHRONIZED, + Opcodes.ACC_PUBLIC)); + + // A method can change native + assertFalse(Tools.isMethodAccessChange(0, + Opcodes.ACC_NATIVE)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC, + Opcodes.ACC_PUBLIC + Opcodes.ACC_NATIVE)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_NATIVE, + 0)); + assertFalse(Tools.isMethodAccessChange(Opcodes.ACC_PUBLIC + Opcodes.ACC_NATIVE, + Opcodes.ACC_PUBLIC)); + } + } |