• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.assertThrows;
21 
22 import dagger.Component;
23 import dagger.Module;
24 import dagger.Provides;
25 import javax.inject.Provider;
26 import org.jspecify.annotations.Nullable;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.junit.runners.JUnit4;
30 
31 @RunWith(JUnit4.class)
32 public final class JspecifyNullableTest {
33   @Component(modules = MyModule.class, dependencies = ComponentDependency.class)
34   interface MyComponent {
getInt()35     Integer getInt();
getInnerType()36     InnerType getInnerType();
getDependencyProvider()37         Provider<Dependency> getDependencyProvider();
38   }
39 
40   interface Dependency {}
41 
42   interface InnerType {}
43 
44   @Module
45   static class MyModule {
46     private final Integer integer;
47     private final InnerType innerType;
48 
MyModule(Integer integer, InnerType innerType)49     MyModule(Integer integer, InnerType innerType) {
50       this.integer = integer;
51       this.innerType = innerType;
52     }
53 
54     @Provides
provideInt()55     @Nullable Integer provideInt() {
56       return integer;
57     }
58 
59     @Provides
provideInnerType()60     @Nullable InnerType provideInnerType() {
61       return innerType;
62     }
63   }
64 
65   @Component(modules = DependencyModule.class)
66   interface ComponentDependency {
dependency()67     @Nullable Dependency dependency();
68   }
69 
70   @Module
71   static class DependencyModule {
72     private final Dependency dependency;
73 
DependencyModule(Dependency dependency)74     DependencyModule(Dependency dependency) {
75       this.dependency = dependency;
76     }
77 
78     @Provides
provideDependency()79     @Nullable Dependency provideDependency() {
80       return dependency;
81     }
82   }
83 
84   @Test
testWithValue()85   public void testWithValue() {
86     MyComponent component = DaggerJspecifyNullableTest_MyComponent.builder()
87         .myModule(new MyModule(15, new InnerType() {}))
88         .componentDependency(
89             DaggerJspecifyNullableTest_ComponentDependency.builder()
90                 .dependencyModule(new DependencyModule(new Dependency() {})).build())
91         .build();
92     assertThat(component.getInt()).isEqualTo(15);
93     assertThat(component.getInnerType()).isNotNull();
94     assertThat(component.getDependencyProvider().get()).isNotNull();
95   }
96 
97   @Test
testWithNull()98   public void testWithNull() {
99     MyComponent component = DaggerJspecifyNullableTest_MyComponent.builder()
100         .myModule(new MyModule(null, null))
101         .componentDependency(
102             DaggerJspecifyNullableTest_ComponentDependency.builder()
103                 .dependencyModule(new DependencyModule(null)).build())
104         .build();
105     NullPointerException expectedException =
106         assertThrows(NullPointerException.class, component::getInt);
107     assertThat(expectedException)
108         .hasMessageThat()
109         .contains("Cannot return null from a non-@Nullable @Provides method");
110     NullPointerException expectedException2 =
111         assertThrows(NullPointerException.class, component::getInnerType);
112     assertThat(expectedException2)
113         .hasMessageThat()
114         .contains("Cannot return null from a non-@Nullable @Provides method");
115     NullPointerException expectedException3 =
116         assertThrows(NullPointerException.class, () -> component.getDependencyProvider().get());
117     assertThat(expectedException3)
118         .hasMessageThat()
119         .contains("Cannot return null from a non-@Nullable @Provides method");
120   }
121 }
122