Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ef3dc8f

Browse files
authored
Improve typing for PluginLoader#loadPlugin(..) (#3242)
Make the method return the lowest common denominator type Follow up to #3220
1 parent 33dc48c commit ef3dc8f

File tree

3 files changed

+176
-29
lines changed

3 files changed

+176
-29
lines changed

src/main/java/org/mockito/internal/configuration/plugins/PluginLoader.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,20 @@ class PluginLoader {
4545
/**
4646
* Scans the classpath for given pluginType. If not found, default class is used.
4747
*/
48-
@SuppressWarnings("unchecked")
4948
<T> T loadPlugin(final Class<T> pluginType) {
50-
return (T) loadPlugin(pluginType, null);
49+
return loadPlugin(pluginType, null);
5150
}
5251

5352
/**
5453
* Scans the classpath for given {@code preferredPluginType}. If not found scan for {@code
5554
* alternatePluginType}. If neither a preferred or alternate plugin is found, default to default
5655
* class of {@code preferredPluginType}.
5756
*
58-
* @return An object of either {@code preferredPluginType} or {@code alternatePluginType}
57+
* @return An object of either {@code preferredPluginType} or {@code alternatePluginType},
58+
* cast to the lowest common denominator in the chain of inheritance
5959
*/
6060
@SuppressWarnings("unchecked")
61-
<PreferredT, AlternateType> Object loadPlugin(
61+
<ReturnT, PreferredT extends ReturnT, AlternateType extends ReturnT> ReturnT loadPlugin(
6262
final Class<PreferredT> preferredPluginType,
6363
final Class<AlternateType> alternatePluginType) {
6464
try {
@@ -74,22 +74,23 @@ <PreferredT, AlternateType> Object loadPlugin(
7474

7575
return plugins.getDefaultPlugin(preferredPluginType);
7676
} catch (final Throwable t) {
77-
return Proxy.newProxyInstance(
78-
preferredPluginType.getClassLoader(),
79-
new Class<?>[] {preferredPluginType},
80-
new InvocationHandler() {
81-
@Override
82-
public Object invoke(Object proxy, Method method, Object[] args)
83-
throws Throwable {
84-
throw new IllegalStateException(
85-
"Could not initialize plugin: "
86-
+ preferredPluginType
87-
+ " (alternate: "
88-
+ alternatePluginType
89-
+ ")",
90-
t);
91-
}
92-
});
77+
return (ReturnT)
78+
Proxy.newProxyInstance(
79+
preferredPluginType.getClassLoader(),
80+
new Class<?>[] {preferredPluginType},
81+
new InvocationHandler() {
82+
@Override
83+
public Object invoke(Object proxy, Method method, Object[] args)
84+
throws Throwable {
85+
throw new IllegalStateException(
86+
"Could not initialize plugin: "
87+
+ preferredPluginType
88+
+ " (alternate: "
89+
+ alternatePluginType
90+
+ ")",
91+
t);
92+
}
93+
});
9394
}
9495
}
9596

src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ class PluginRegistry {
4949
new PluginLoader(pluginSwitch).loadPlugins(MockResolver.class);
5050

5151
private final DoNotMockEnforcerWithType doNotMockEnforcer =
52-
(DoNotMockEnforcerWithType)
53-
(new PluginLoader(pluginSwitch)
54-
.loadPlugin(DoNotMockEnforcerWithType.class, DoNotMockEnforcer.class));
52+
new PluginLoader(pluginSwitch)
53+
.loadPlugin(DoNotMockEnforcerWithType.class, DoNotMockEnforcer.class);
5554

5655
PluginRegistry() {
5756
instantiatorProvider =

src/test/java/org/mockito/internal/configuration/plugins/PluginLoaderTest.java

Lines changed: 153 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
*/
55
package org.mockito.internal.configuration.plugins;
66

7-
import static org.junit.Assert.assertNotNull;
87
import static org.junit.Assert.assertSame;
98
import static org.mockito.BDDMockito.willReturn;
9+
import static org.mockito.Mockito.never;
10+
import static org.mockito.Mockito.verify;
1011
import static org.mockito.Mockito.when;
1112

1213
import org.assertj.core.api.Assertions;
@@ -29,13 +30,27 @@ public class PluginLoaderTest {
2930

3031
@Test
3132
public void loads_plugin() {
32-
when(initializer.loadImpl(FooPlugin.class)).thenReturn(new FooPlugin());
33+
FooPlugin expected = new FooPlugin();
34+
when(initializer.loadImpl(FooPlugin.class)).thenReturn(expected);
3335

3436
// when
3537
FooPlugin plugin = loader.loadPlugin(FooPlugin.class);
3638

3739
// then
38-
assertNotNull(plugin);
40+
assertSame(expected, plugin);
41+
}
42+
43+
@Test
44+
public void loads_preferred_plugin() {
45+
FooPlugin expected = new FooPlugin();
46+
willReturn(expected).given(initializer).loadImpl(FooPlugin.class);
47+
48+
// when
49+
Object plugin = loader.loadPlugin(FooPlugin.class, BarPlugin.class);
50+
51+
// then
52+
assertSame(expected, plugin);
53+
verify(initializer, never()).loadImpl(BarPlugin.class);
3954
}
4055

4156
@Test
@@ -48,7 +63,7 @@ public void loads_alternative_plugin() {
4863
Object plugin = loader.loadPlugin(FooPlugin.class, BarPlugin.class);
4964

5065
// then
51-
assertSame(plugin, expected);
66+
assertSame(expected, plugin);
5267
}
5368

5469
@Test
@@ -62,7 +77,7 @@ public void loads_default_plugin() {
6277
Object plugin = loader.loadPlugin(FooPlugin.class, BarPlugin.class);
6378

6479
// then
65-
assertSame(plugin, expected);
80+
assertSame(expected, plugin);
6681
}
6782

6883
@Test
@@ -87,9 +102,141 @@ public void call() throws Throwable {
87102
.hasCause(cause);
88103
}
89104

105+
@Test
106+
public void loads_preferred_plugin_inheritance() {
107+
FooChildPlugin expected = new FooChildPlugin();
108+
willReturn(expected).given(initializer).loadImpl(Foo.class);
109+
110+
// when
111+
Foo plugin = loader.loadPlugin(Foo.class, FooChildPlugin.class);
112+
113+
// then
114+
assertSame(expected, plugin);
115+
verify(initializer, never()).loadImpl(FooChildPlugin.class);
116+
}
117+
118+
@Test
119+
public void loads_alternative_plugin_inheritance() {
120+
willReturn(null).given(initializer).loadImpl(Bar.class);
121+
BarChildPlugin expected = new BarChildPlugin();
122+
willReturn(expected).given(initializer).loadImpl(BarChildPlugin.class);
123+
124+
// when
125+
Bar plugin = loader.loadPlugin(Bar.class, BarChildPlugin.class);
126+
127+
// then
128+
assertSame(expected, plugin);
129+
}
130+
131+
@Test
132+
public void loads_default_plugin_inheritance() {
133+
willReturn(null).given(initializer).loadImpl(Foo.class);
134+
willReturn(null).given(initializer).loadImpl(FooChildPlugin.class);
135+
FooChildPlugin expected = new FooChildPlugin();
136+
willReturn(expected).given(plugins).getDefaultPlugin(Foo.class);
137+
138+
// when
139+
Foo plugin = loader.loadPlugin(Foo.class, FooChildPlugin.class);
140+
141+
// then
142+
assertSame(expected, plugin);
143+
}
144+
145+
@Test
146+
public void loads_preferred_plugin_inheritance_reversed() {
147+
FooChildPlugin expected = new FooChildPlugin();
148+
willReturn(expected).given(initializer).loadImpl(FooChildPlugin.class);
149+
150+
// when
151+
Foo plugin = loader.loadPlugin(FooChildPlugin.class, Foo.class);
152+
153+
// then
154+
assertSame(expected, plugin);
155+
verify(initializer, never()).loadImpl(Foo.class);
156+
}
157+
158+
@Test
159+
public void loads_alternative_plugin_inheritance_reversed() {
160+
willReturn(null).given(initializer).loadImpl(BarChildPlugin.class);
161+
BarChildPlugin expected = new BarChildPlugin();
162+
willReturn(expected).given(initializer).loadImpl(Bar.class);
163+
164+
// when
165+
Bar plugin = loader.loadPlugin(BarChildPlugin.class, Bar.class);
166+
167+
// then
168+
assertSame(expected, plugin);
169+
}
170+
171+
@Test
172+
public void loads_default_plugin_inheritance_reversed() {
173+
willReturn(null).given(initializer).loadImpl(Foo.class);
174+
willReturn(null).given(initializer).loadImpl(FooChildPlugin.class);
175+
FooChildPlugin expected = new FooChildPlugin();
176+
willReturn(expected).given(plugins).getDefaultPlugin(FooChildPlugin.class);
177+
178+
// when
179+
Foo plugin = loader.loadPlugin(FooChildPlugin.class, Foo.class);
180+
181+
// then
182+
assertSame(expected, plugin);
183+
}
184+
185+
@Test
186+
public void loads_preferred_plugin_inheritance_lowest_common_denominator() {
187+
FooBarChildPlugin1 expected = new FooBarChildPlugin1();
188+
willReturn(expected).given(initializer).loadImpl(FooBarChildPlugin1.class);
189+
190+
// when
191+
FooBar plugin = loader.loadPlugin(FooBarChildPlugin1.class, FooBarChildPlugin2.class);
192+
193+
// then
194+
assertSame(expected, plugin);
195+
verify(initializer, never()).loadImpl(FooBarChildPlugin2.class);
196+
}
197+
198+
@Test
199+
public void loads_alternative_plugin_inheritance_lowest_common_denominator() {
200+
willReturn(null).given(initializer).loadImpl(FooBarChildPlugin1.class);
201+
FooBarChildPlugin2 expected = new FooBarChildPlugin2();
202+
willReturn(expected).given(initializer).loadImpl(FooBarChildPlugin2.class);
203+
204+
// when
205+
FooBar plugin = loader.loadPlugin(FooBarChildPlugin1.class, FooBarChildPlugin2.class);
206+
207+
// then
208+
assertSame(expected, plugin);
209+
}
210+
211+
@Test
212+
public void loads_default_plugin_inheritance_lowest_common_denominator() {
213+
willReturn(null).given(initializer).loadImpl(FooBarChildPlugin1.class);
214+
willReturn(null).given(initializer).loadImpl(FooBarChildPlugin2.class);
215+
FooBarChildPlugin1 expected = new FooBarChildPlugin1();
216+
willReturn(expected).given(plugins).getDefaultPlugin(FooBarChildPlugin1.class);
217+
218+
// when
219+
FooBar plugin = loader.loadPlugin(FooBarChildPlugin1.class, FooBarChildPlugin2.class);
220+
221+
// then
222+
assertSame(expected, plugin);
223+
}
224+
90225
static class FooPlugin {}
91226

92227
static class BarPlugin {}
93228

94-
static interface Foo {}
229+
interface Foo {}
230+
231+
interface Bar {}
232+
233+
static class BarChildPlugin implements Bar {}
234+
235+
static class FooChildPlugin implements Foo {}
236+
237+
interface FooBar {}
238+
239+
static class FooBarChildPlugin1 implements FooBar {}
240+
241+
static class FooBarChildPlugin2 implements FooBar {}
95242
}

0 commit comments

Comments
 (0)