Skip to content

Commit 176ec39

Browse files
authored
Add support for equals, hashCode and toString on proxy instances. (#68)
* Add support for equals, hashCode and toString on proxy instances.
1 parent 635dfd3 commit 176ec39

3 files changed

Lines changed: 71 additions & 8 deletions

File tree

google-ads/src/main/java/com/google/ads/googleads/lib/catalog/ApiCatalogImpl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import com.google.common.base.Preconditions;
2121
import com.google.common.collect.ImmutableMap;
2222
import com.google.common.collect.ImmutableSortedSet;
23+
import com.google.common.reflect.AbstractInvocationHandler;
2324
import com.google.common.reflect.Reflection;
24-
import java.lang.reflect.InvocationHandler;
2525
import java.lang.reflect.Method;
2626
import java.util.Collection;
2727
import java.util.SortedSet;
@@ -68,11 +68,12 @@ public GoogleAdsAllVersions createAllVersionsClient(
6868
Preconditions.checkNotNull(
6969
credentials, "Credentials are required to create GoogleAdsAllVersions interface.");
7070
return Reflection.newProxy(
71-
GoogleAdsAllVersions.class, new GoogleAdsAllVersionsInvocationHandler(provider, credentials));
71+
GoogleAdsAllVersions.class,
72+
new GoogleAdsAllVersionsInvocationHandler(provider, credentials));
7273
}
7374

7475
/** A dynamic proxy implementation of GoogleAdsAllVersions. */
75-
private static class GoogleAdsAllVersionsInvocationHandler implements InvocationHandler {
76+
private static class GoogleAdsAllVersionsInvocationHandler extends AbstractInvocationHandler {
7677

7778
private final ImmutableMap<Method, Object> clientFactories;
7879

@@ -83,7 +84,7 @@ public GoogleAdsAllVersionsInvocationHandler(
8384
}
8485

8586
@Override
86-
public Object invoke(Object proxy, Method method, Object[] args) {
87+
protected Object handleInvocation(Object proxy, Method method, Object[] args) {
8788
return clientFactories.get(method);
8889
}
8990

@@ -94,8 +95,7 @@ private static ImmutableMap<Method, Object> cacheClientFactories(
9495
for (Method method : GoogleAdsAllVersions.class.getMethods()) {
9596
builder.put(
9697
method,
97-
GoogleAdsVersionFactory.createProxy(
98-
method.getReturnType(), provider, credentials));
98+
GoogleAdsVersionFactory.createProxy(method.getReturnType(), provider, credentials));
9999
}
100100
return builder.build();
101101
}

google-ads/src/main/java/com/google/ads/googleads/lib/catalog/GoogleAdsVersionFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.auth.Credentials;
2424
import com.google.common.base.Preconditions;
2525
import com.google.common.collect.ImmutableMap;
26+
import com.google.common.reflect.AbstractInvocationHandler;
2627
import com.google.common.reflect.Reflection;
2728
import java.io.IOException;
2829
import java.lang.reflect.InvocationHandler;
@@ -65,7 +66,7 @@ public static <T> T createProxy(
6566
}
6667

6768
/** Implements InvocationHandler for the dynamic proxy implementation of VersionDescriptor. */
68-
private static class VersionDescriptorInvocationHandler implements InvocationHandler {
69+
private static class VersionDescriptorInvocationHandler extends AbstractInvocationHandler {
6970

7071
private final ImmutableMap<Class, Method> clientCreators;
7172
private final ImmutableMap<Method, Method> settingsBuilders;
@@ -94,7 +95,7 @@ private VersionDescriptorInvocationHandler(
9495
}
9596

9697
@Override
97-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
98+
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
9899
ClientSettings settings = createClientSettings(method);
99100
return createServiceClient(method.getReturnType(), settings);
100101
}

google-ads/src/test/java/com/google/ads/googleads/lib/GoogleAdsClientTest.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static org.junit.Assert.assertEquals;
1818
import static org.junit.Assert.assertFalse;
19+
import static org.junit.Assert.assertNotEquals;
1920
import static org.junit.Assert.assertNotNull;
2021
import static org.junit.Assert.assertNull;
2122
import static org.junit.Assert.assertThat;
@@ -338,13 +339,74 @@ public void exceptionTransformedToGoogleAdsException() {
338339
}
339340
}
340341

342+
/** Ensure that can set endpoint on default transport channel. */
341343
@Test
342344
public void transportChannelProvider_defaultRequiresEndpoint() {
343345
assertTrue(
344346
"Default TransportChannelProvider must accept endpoint.",
345347
GoogleAdsClient.newBuilder().getTransportChannelProvider().needsEndpoint());
346348
}
347349

350+
/** Ensure that hashCode doesn't collide for a test instance. */
351+
@Test
352+
public void hashCode_doesNotCollide() {
353+
GoogleAdsClient clientA =
354+
GoogleAdsClient.newBuilder()
355+
.setCredentials(fakeCredentials)
356+
.setDeveloperToken(DEVELOPER_TOKEN)
357+
.build();
358+
GoogleAdsClient clientB =
359+
GoogleAdsClient.newBuilder()
360+
.setCredentials(fakeCredentials)
361+
.setDeveloperToken(DEVELOPER_TOKEN + "asdf")
362+
.build();
363+
// Granted there could be hash collisions, but this should not happen for this test case.
364+
assertNotEquals(
365+
"Clients with distinct params should have distinct hashCodes",
366+
clientA.hashCode(),
367+
clientB.hashCode());
368+
}
369+
370+
/** Ensures that equals is true for A == B. */
371+
@Test
372+
public void equals_equalIfSameInstance() {
373+
GoogleAdsClient client =
374+
GoogleAdsClient.newBuilder()
375+
.setCredentials(fakeCredentials)
376+
.setDeveloperToken(DEVELOPER_TOKEN)
377+
.build();
378+
assertEquals("same instance should be equal", client, client);
379+
}
380+
381+
/** Ensures that equals is false for A != B, with same config. */
382+
@Test
383+
public void equals_notEqualIfDifferentInstance() {
384+
GoogleAdsClient clientA =
385+
GoogleAdsClient.newBuilder()
386+
.setCredentials(fakeCredentials)
387+
.setDeveloperToken(DEVELOPER_TOKEN)
388+
.build();
389+
GoogleAdsClient clientB =
390+
GoogleAdsClient.newBuilder()
391+
.setCredentials(fakeCredentials)
392+
.setDeveloperToken(DEVELOPER_TOKEN)
393+
.build();
394+
assertNotEquals("different instances should not be equal", clientA, clientB);
395+
}
396+
397+
/** Ensures that toString returns a nonnull value with length() > 0. */
398+
@Test
399+
public void toString_returnsNotNull() {
400+
GoogleAdsClient client =
401+
GoogleAdsClient.newBuilder()
402+
.setCredentials(fakeCredentials)
403+
.setDeveloperToken(DEVELOPER_TOKEN)
404+
.build();
405+
String toString = client.toString();
406+
assertNotNull("toString should return a non-null string", toString);
407+
assertFalse("toString should return a non-empty string", toString.isEmpty());
408+
}
409+
348410
/** Creates an GoogleAdsClient using mock credentials. */
349411
private GoogleAdsClient createTestGoogleAdsClient() {
350412
return GoogleAdsClient.newBuilder()

0 commit comments

Comments
 (0)