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