/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.devtools.j2objc.translate;
import com.google.devtools.j2objc.GenerationTest;
import java.io.IOException;
/**
* Unit tests for {@link AbstractMethodRewriter}.
*
* @author Tom Ball
*/
public class AbstractMethodRewriterTest extends GenerationTest {
/**
* Verifies that a pragma ignored is added when an abstract class does not
* implement all interface methods.
*/
public void testAbstractMethodsAdded() throws IOException {
String source =
"import java.util.Iterator; public abstract class Test implements Iterator<Test> { "
+ "public boolean hasNext() { return true; } }";
String translation = translateSourceFile(source, "Test", "Test.m");
assertTranslation(translation, "#pragma clang diagnostic ignored \"-Wprotocol\"");
}
/**
* Verify that super-interface methods are checked.
*/
public void testAbstractClassGrandfatherInterface() throws IOException {
String source =
"public class Test {"
+ " public interface I1 { void foo(); } "
+ " public interface I2 extends I1 { } "
+ " public abstract class Inner implements I2 { } }";
String translation = translateSourceFile(source, "Test", "Test.m");
assertTranslation(translation, "#pragma clang diagnostic ignored \"-Wprotocol\"");
}
public void testAddsPragmaToAbstractEnum() throws IOException {
String interfaceSource = "interface I { public int foo(); }";
String enumSource =
"enum E implements I { "
+ " A { public int foo() { return 42; } },"
+ " B { public int foo() { return -1; } } }";
addSourceFile(interfaceSource, "I.java");
addSourceFile(enumSource, "E.java");
String translation = translateSourceFile("E", "E.m");
assertTranslation(translation, "#pragma clang diagnostic ignored \"-Wprotocol\"");
}
public void testMethodAddedForSpecifiedTypeArg() throws IOException {
addSourceFile("interface A<T> { T foo(); }", "A.java");
addSourceFile("interface B extends A<String> {}", "B.java");
addSourceFile("abstract class C implements A<String> {}", "C.java");
String aHeader = translateSourceFile("A", "A.h");
String bHeader = translateSourceFile("B", "B.h");
String bSource = getTranslatedFile("B.m");
String cHeader = translateSourceFile("C", "C.h");
String cSource = getTranslatedFile("C.m");
assertTranslation(aHeader, "- (id)foo;");
assertTranslation(bHeader, "- (NSString *)foo;");
// The added "foo" method should not appear in metadata.
assertNotInTranslation(bSource, "foo");
assertTranslation(cHeader, "- (NSString *)foo;");
// The added "foo" method should not appear in metadata or have an implementation.
assertNotInTranslation(cSource, "foo");
}
public void testMethodAddedForMethodInheritedFromMultipleInterfaces() throws IOException {
addSourceFile("interface A { java.io.Serializable foo(); }", "A.java");
addSourceFile("interface B { String foo(); }", "B.java");
addSourceFile("abstract class C implements A, B {}", "C.java");
String cHeader = translateSourceFile("C", "C.h");
String cSource = translateSourceFile("C", "C.m");
assertTranslation(cHeader, "- (NSString *)foo;");
assertNotInTranslation(cSource, "foo");
}
public void testGenericPrivateMethodNotAdded() throws IOException {
String superSource = "abstract class Super<T> { "
+ " private T returnT() { return null; } "
+ "}";
String subSource = "class Sub extends Super<Void> {}";
addSourceFile(superSource, "Super.java");
addSourceFile(subSource, "Sub.java");
String superTranslation = translateSourceFile("Super", "Super.m");
String subTranslation = translateSourceFile("Sub", "Sub.m");
// Super translation should contain the generic private method declaration.
assertTranslation(superTranslation, "- (id)returnT;");
// But Sub translation should not even though the return type is now resolved.
assertNotInTranslation(subTranslation, "returnT");
}
}