1 package org.robolectric.annotation.processing.validator; 2 3 import static com.google.common.truth.Fact.simpleFact; 4 import static com.google.common.truth.Truth.assertAbout; 5 import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; 6 import static org.robolectric.annotation.processing.Utils.DEFAULT_OPTS; 7 8 import com.google.common.collect.ImmutableList; 9 import com.google.common.truth.FailureMetadata; 10 import com.google.common.truth.Subject; 11 import com.google.testing.compile.CompileTester; 12 import com.google.testing.compile.CompileTester.LineClause; 13 import com.google.testing.compile.CompileTester.SuccessfulCompilationClause; 14 import com.google.testing.compile.CompileTester.UnsuccessfulCompilationClause; 15 import com.google.testing.compile.JavaFileObjects; 16 import javax.tools.JavaFileObject; 17 import org.robolectric.annotation.processing.RobolectricProcessor; 18 import org.robolectric.annotation.processing.Utils; 19 20 public final class SingleClassSubject extends Subject { 21 singleClass()22 public static Subject.Factory<SingleClassSubject, String> singleClass() { 23 24 return SingleClassSubject::new; 25 } 26 27 28 JavaFileObject source; 29 CompileTester tester; 30 SingleClassSubject(FailureMetadata failureMetadata, String subject)31 public SingleClassSubject(FailureMetadata failureMetadata, String subject) { 32 super(failureMetadata, subject); 33 source = JavaFileObjects.forResource(Utils.toResourcePath(subject)); 34 tester = 35 assertAbout(javaSources()) 36 .that(ImmutableList.of(source, Utils.SHADOW_EXTRACTOR_SOURCE)) 37 .processedWith(new RobolectricProcessor(DEFAULT_OPTS)); 38 } 39 compilesWithoutError()40 public SuccessfulCompilationClause compilesWithoutError() { 41 try { 42 return tester.compilesWithoutError(); 43 } catch (AssertionError e) { 44 failWithoutActual(simpleFact(e.getMessage())); 45 } 46 return null; 47 } 48 failsToCompile()49 public SingleFileClause failsToCompile() { 50 try { 51 return new SingleFileClause(tester.failsToCompile(), source); 52 } catch (AssertionError e) { 53 failWithoutActual(simpleFact(e.getMessage())); 54 } 55 return null; 56 } 57 58 final class SingleFileClause implements CompileTester.ChainingClause<SingleFileClause> { 59 60 UnsuccessfulCompilationClause unsuccessful; 61 JavaFileObject source; 62 SingleFileClause(UnsuccessfulCompilationClause unsuccessful, JavaFileObject source)63 public SingleFileClause(UnsuccessfulCompilationClause unsuccessful, JavaFileObject source) { 64 this.unsuccessful = unsuccessful; 65 this.source = source; 66 } 67 withErrorContaining(final String messageFragment)68 public SingleLineClause withErrorContaining(final String messageFragment) { 69 try { 70 return new SingleLineClause(unsuccessful.withErrorContaining(messageFragment).in(source)); 71 } catch (AssertionError e) { 72 failWithoutActual(simpleFact(e.getMessage())); 73 } 74 return null; 75 } 76 withNoErrorContaining(final String messageFragment)77 public SingleFileClause withNoErrorContaining(final String messageFragment) { 78 try { 79 unsuccessful.withErrorContaining(messageFragment); 80 } catch (AssertionError e) { 81 return this; 82 } 83 failWithoutActual( 84 simpleFact( 85 "Shouldn't have found any errors containing " + messageFragment + ", but we did")); 86 87 return this; 88 } 89 90 @Override and()91 public SingleFileClause and() { 92 return this; 93 } 94 95 final class SingleLineClause implements CompileTester.ChainingClause<SingleFileClause> { 96 97 LineClause lineClause; 98 SingleLineClause(LineClause lineClause)99 public SingleLineClause(LineClause lineClause) { 100 this.lineClause = lineClause; 101 } 102 onLine(long lineNumber)103 public CompileTester.ChainingClause<SingleFileClause> onLine(long lineNumber) { 104 try { 105 lineClause.onLine(lineNumber); 106 return new CompileTester.ChainingClause<SingleFileClause>() { 107 @Override 108 public SingleFileClause and() { 109 return SingleFileClause.this; 110 } 111 }; 112 } catch (AssertionError e) { 113 failWithoutActual(simpleFact(e.getMessage())); 114 } 115 return null; 116 } 117 118 @Override and()119 public SingleFileClause and() { 120 return SingleFileClause.this; 121 } 122 123 } 124 } 125 } 126