1 package com.google.inject.testing.throwingproviders; 2 3 import static com.google.common.truth.Truth.assertAbout; 4 5 import com.google.common.truth.FailureMetadata; 6 import com.google.common.truth.Subject; 7 import com.google.common.truth.ThrowableSubject; 8 import com.google.inject.throwingproviders.CheckedProvider; 9 import javax.annotation.Nullable; 10 11 /** 12 * Truth {@link Subject} for use with {@link CheckedProvider} classes. 13 * 14 * @author eatnumber1@google.com (Russ Harmon) 15 */ 16 public final class CheckedProviderSubject<T, P extends CheckedProvider<T>> 17 extends Subject<CheckedProviderSubject<T, P>, P> { 18 19 private static final class CheckedProviderSubjectFactory<T, P extends CheckedProvider<T>> 20 implements Subject.Factory<CheckedProviderSubject<T, P>, P> { 21 @Override createSubject( FailureMetadata failureMetadata, @Nullable P target)22 public CheckedProviderSubject<T, P> createSubject( 23 FailureMetadata failureMetadata, @Nullable P target) { 24 return new CheckedProviderSubject<T, P>(failureMetadata, target); 25 } 26 } 27 28 public static <T, P extends CheckedProvider<T>> checkedProviders()29 Subject.Factory<CheckedProviderSubject<T, P>, P> checkedProviders() { 30 return new CheckedProviderSubjectFactory<>(); 31 } 32 assertThat( @ullable P provider)33 public static <T, P extends CheckedProvider<T>> CheckedProviderSubject<T, P> assertThat( 34 @Nullable P provider) { 35 return assertAbout(CheckedProviderSubject.<T, P>checkedProviders()).that(provider); 36 } 37 CheckedProviderSubject(FailureMetadata failureMetadata, @Nullable P subject)38 private CheckedProviderSubject(FailureMetadata failureMetadata, @Nullable P subject) { 39 super(failureMetadata, subject); 40 } 41 42 /** 43 * Allows for assertions on the value provided by this provider. 44 * 45 * <p>The value provided by a checked provider is the object returned by a call to {@link 46 * CheckedProvider#get} 47 * 48 * @return a {@link Subject} for asserting against the return value of {@link CheckedProvider#get} 49 */ providedValue()50 public Subject<?, Object> providedValue() { 51 P provider = actual(); 52 T got; 53 try { 54 got = provider.get(); 55 } catch (Exception e) { 56 failWithRawMessageAndCause( 57 String.format("checked provider <%s> threw an exception", provider), e); 58 return ignoreCheck().that(new Object()); 59 } 60 return check().withMessage("value provided by <%s>", provider).that(got); 61 } 62 63 /** 64 * Allows for assertions on the exception thrown by this provider. 65 * 66 * <p>The exception thrown by a checked provider is the {@link Throwable} thrown by a call to 67 * {@link CheckedProvider#get} 68 * 69 * @return a {@link ThrowableSubject} for asserting against the {@link Throwable} thrown by {@link 70 * CheckedProvider#get} 71 */ thrownException()72 public ThrowableSubject thrownException() { 73 P provider = actual(); 74 T got; 75 try { 76 got = provider.get(); 77 } catch (Throwable e) { 78 return check().withMessage("exception thrown by <%s>", provider).that(e); 79 } 80 failWithBadResults("threw", "an exception", "provided", got); 81 return ignoreCheck().that(new Throwable()); 82 } 83 } 84