1 /* 2 * Copyright (C) 2015 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.functional.nullables; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.fail; 21 22 import javax.inject.Provider; 23 import org.junit.Test; 24 import org.junit.runner.RunWith; 25 import org.junit.runners.JUnit4; 26 27 @RunWith(JUnit4.class) 28 public class NullabilityTest { testNullability_provides()29 @Test public void testNullability_provides() { 30 NullModule module = new NullModule(); 31 NullComponent component = DaggerNullComponent.builder().nullModule(module).build(); 32 33 // Can't construct NullFoo because it depends on Number, and Number was null. 34 try { 35 component.nullFoo(); 36 fail(); 37 } catch (NullPointerException npe) { 38 assertThat(npe) 39 .hasMessageThat() 40 .isEqualTo("Cannot return null from a non-@Nullable @Provides method"); 41 } 42 43 // set number to non-null so we can create 44 module.numberValue = 1; 45 NullFoo nullFoo = component.nullFoo(); 46 47 // Then set it back to null so we can test its providers. 48 module.numberValue = null; 49 validate(true, nullFoo.string, nullFoo.stringProvider, nullFoo.numberProvider); 50 validate(true, nullFoo.methodInjectedString, nullFoo.methodInjectedStringProvider, 51 nullFoo.methodInjectedNumberProvider); 52 validate(true, nullFoo.fieldInjectedString, nullFoo.fieldInjectedStringProvider, 53 nullFoo.fieldInjectedNumberProvider); 54 } 55 testNullability_reusuable()56 @Test public void testNullability_reusuable() { 57 NullModule module = new NullModule(); 58 NullComponent component = DaggerNullComponent.builder().nullModule(module).build(); 59 60 // Test that the @Nullable @Reusuable binding is cached properly even when the value is null. 61 assertThat(module.integerCallCount).isEqualTo(0); 62 assertThat(component.integer()).isNull(); 63 assertThat(module.integerCallCount).isEqualTo(1); 64 assertThat(component.integer()).isNull(); 65 assertThat(module.integerCallCount).isEqualTo(1); 66 } 67 testNullability_components()68 @Test public void testNullability_components() { 69 NullComponent nullComponent = new NullComponent() { 70 @Override public Provider<String> stringProvider() { 71 return new Provider<String>() { 72 @Override public String get() { 73 return null; 74 } 75 }; 76 } 77 78 @Override public String string() { 79 return null; 80 } 81 82 @Override public Provider<Number> numberProvider() { 83 return new Provider<Number>() { 84 @Override public Number get() { 85 return null; 86 } 87 }; 88 } 89 90 @Override public Number number() { 91 return null; 92 } 93 94 @Override public NullFoo nullFoo() { 95 return null; 96 } 97 98 @Override public Integer integer() { 99 return null; 100 } 101 }; 102 NullComponentWithDependency component = 103 DaggerNullComponentWithDependency.builder().nullComponent(nullComponent).build(); 104 validate(false, component.string(), component.stringProvider(), component.numberProvider()); 105 106 // Also validate that the component's number() method fails 107 try { 108 component.number(); 109 fail(); 110 } catch (NullPointerException npe) { 111 assertThat(npe) 112 .hasMessageThat() 113 .isEqualTo("Cannot return null from a non-@Nullable component method"); 114 } 115 } 116 validate(boolean fromProvides, String string, Provider<String> stringProvider, Provider<Number> numberProvider)117 private void validate(boolean fromProvides, 118 String string, 119 Provider<String> stringProvider, 120 Provider<Number> numberProvider) { 121 assertThat(string).isNull(); 122 assertThat(numberProvider).isNotNull(); 123 try { 124 numberProvider.get(); 125 fail(); 126 } catch (NullPointerException npe) { 127 assertThat(npe) 128 .hasMessageThat() 129 .isEqualTo( 130 "Cannot return null from a non-@Nullable " 131 + (fromProvides ? "@Provides" : "component") 132 + " method"); 133 } 134 assertThat(stringProvider.get()).isNull(); 135 } 136 } 137