Java

Форк
0
/
ForwardingWrapperTesterTest.java 
627 строк · 15.7 Кб
1
/*
2
 * Copyright (C) 2012 The Guava 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 com.google.common.testing.anotherpackage;
18

19
import static com.google.common.truth.Truth.assertThat;
20
import static org.junit.Assert.assertThrows;
21

22
import com.google.common.base.Equivalence;
23
import com.google.common.base.Function;
24
import com.google.common.base.Functions;
25
import com.google.common.base.Joiner;
26
import com.google.common.base.Predicate;
27
import com.google.common.collect.Ordering;
28
import com.google.common.primitives.UnsignedInteger;
29
import com.google.common.primitives.UnsignedLong;
30
import com.google.common.testing.ForwardingWrapperTester;
31
import com.google.common.testing.NullPointerTester;
32
import com.google.errorprone.annotations.CanIgnoreReturnValue;
33
import java.io.InputStream;
34
import java.nio.charset.Charset;
35
import java.util.concurrent.TimeUnit;
36
import java.util.regex.Pattern;
37
import junit.framework.AssertionFailedError;
38
import junit.framework.TestCase;
39
import org.checkerframework.checker.nullness.qual.Nullable;
40

41
/**
42
 * Tests for {@link ForwardingWrapperTester}. Live in a different package to detect reflection
43
 * access issues, if any.
44
 *
45
 * @author Ben Yu
46
 */
47
public class ForwardingWrapperTesterTest extends TestCase {
48

49
  private final ForwardingWrapperTester tester = new ForwardingWrapperTester();
50

51
  public void testGoodForwarder() {
52
    tester.testForwarding(
53
        Arithmetic.class,
54
        new Function<Arithmetic, Arithmetic>() {
55
          @Override
56
          public Arithmetic apply(Arithmetic arithmetic) {
57
            return new ForwardingArithmetic(arithmetic);
58
          }
59
        });
60
    tester.testForwarding(
61
        ParameterTypesDifferent.class,
62
        new Function<ParameterTypesDifferent, ParameterTypesDifferent>() {
63
          @Override
64
          public ParameterTypesDifferent apply(ParameterTypesDifferent delegate) {
65
            return new ParameterTypesDifferentForwarder(delegate);
66
          }
67
        });
68
  }
69

70
  public void testVoidMethodForwarding() {
71
    tester.testForwarding(
72
        Runnable.class,
73
        new Function<Runnable, Runnable>() {
74
          @Override
75
          public Runnable apply(final Runnable runnable) {
76
            return new ForwardingRunnable(runnable);
77
          }
78
        });
79
  }
80

81
  public void testToStringForwarding() {
82
    tester.testForwarding(
83
        Runnable.class,
84
        new Function<Runnable, Runnable>() {
85
          @Override
86
          public Runnable apply(final Runnable runnable) {
87
            return new ForwardingRunnable(runnable) {
88
              @Override
89
              public String toString() {
90
                return runnable.toString();
91
              }
92
            };
93
          }
94
        });
95
  }
96

97
  public void testFailsToForwardToString() {
98
    assertFailure(
99
        Runnable.class,
100
        new Function<Runnable, Runnable>() {
101
          @Override
102
          public Runnable apply(final Runnable runnable) {
103
            return new ForwardingRunnable(runnable) {
104
              @Override
105
              public String toString() {
106
                return "";
107
              }
108
            };
109
          }
110
        },
111
        "toString()");
112
  }
113

114
  public void testFailsToForwardHashCode() {
115
    tester.includingEquals();
116
    assertFailure(
117
        Runnable.class,
118
        new Function<Runnable, Runnable>() {
119
          @Override
120
          public Runnable apply(final Runnable runnable) {
121
            return new ForwardingRunnable(runnable) {
122

123
              @SuppressWarnings("EqualsHashCode")
124
              @Override
125
              public boolean equals(@Nullable Object o) {
126
                if (o instanceof ForwardingRunnable) {
127
                  ForwardingRunnable that = (ForwardingRunnable) o;
128
                  return runnable.equals(that.runnable);
129
                }
130
                return false;
131
              }
132
            };
133
          }
134
        },
135
        "Runnable");
136
  }
137

138
  public void testEqualsAndHashCodeForwarded() {
139
    tester.includingEquals();
140
    tester.testForwarding(
141
        Runnable.class,
142
        new Function<Runnable, Runnable>() {
143
          @Override
144
          public Runnable apply(final Runnable runnable) {
145
            return new ForwardingRunnable(runnable) {
146
              @Override
147
              public boolean equals(@Nullable Object o) {
148
                if (o instanceof ForwardingRunnable) {
149
                  ForwardingRunnable that = (ForwardingRunnable) o;
150
                  return runnable.equals(that.runnable);
151
                }
152
                return false;
153
              }
154

155
              @Override
156
              public int hashCode() {
157
                return runnable.hashCode();
158
              }
159
            };
160
          }
161
        });
162
  }
163

164
  public void testFailsToForwardEquals() {
165
    tester.includingEquals();
166
    assertFailure(
167
        Runnable.class,
168
        new Function<Runnable, Runnable>() {
169
          @Override
170
          public Runnable apply(final Runnable runnable) {
171
            return new ForwardingRunnable(runnable) {
172
              @Override
173
              public int hashCode() {
174
                return runnable.hashCode();
175
              }
176
            };
177
          }
178
        },
179
        "Runnable");
180
  }
181

182
  public void testFailsToForward() {
183
    assertFailure(
184
        Runnable.class,
185
        new Function<Runnable, Runnable>() {
186
          @Override
187
          public Runnable apply(Runnable runnable) {
188
            return new ForwardingRunnable(runnable) {
189
              @Override
190
              public void run() {}
191
            };
192
          }
193
        },
194
        "run()",
195
        "Failed to forward");
196
  }
197

198
  public void testRedundantForwarding() {
199
    assertFailure(
200
        Runnable.class,
201
        new Function<Runnable, Runnable>() {
202
          @Override
203
          public Runnable apply(final Runnable runnable) {
204
            return new Runnable() {
205
              @Override
206
              public void run() {
207
                runnable.run();
208
                runnable.run();
209
              }
210
            };
211
          }
212
        },
213
        "run()",
214
        "invoked more than once");
215
  }
216

217
  public void testFailsToForwardParameters() {
218
    assertFailure(
219
        Adder.class,
220
        new Function<Adder, Adder>() {
221
          @Override
222
          public Adder apply(Adder adder) {
223
            return new FailsToForwardParameters(adder);
224
          }
225
        },
226
        "add(",
227
        "Parameter #0");
228
  }
229

230
  public void testForwardsToTheWrongMethod() {
231
    assertFailure(
232
        Arithmetic.class,
233
        new Function<Arithmetic, Arithmetic>() {
234
          @Override
235
          public Arithmetic apply(Arithmetic adder) {
236
            return new ForwardsToTheWrongMethod(adder);
237
          }
238
        },
239
        "minus");
240
  }
241

242
  public void testFailsToForwardReturnValue() {
243
    assertFailure(
244
        Adder.class,
245
        new Function<Adder, Adder>() {
246
          @Override
247
          public Adder apply(Adder adder) {
248
            return new FailsToForwardReturnValue(adder);
249
          }
250
        },
251
        "add(",
252
        "Return value");
253
  }
254

255
  public void testFailsToPropagateException() {
256
    assertFailure(
257
        Adder.class,
258
        new Function<Adder, Adder>() {
259
          @Override
260
          public Adder apply(Adder adder) {
261
            return new FailsToPropagateException(adder);
262
          }
263
        },
264
        "add(",
265
        "exception");
266
  }
267

268
  public void testNotInterfaceType() {
269
    assertThrows(
270
        IllegalArgumentException.class,
271
        () ->
272
            new ForwardingWrapperTester()
273
                .testForwarding(String.class, Functions.<String>identity()));
274
  }
275

276
  public void testNulls() {
277
    new NullPointerTester()
278
        .setDefault(Class.class, Runnable.class)
279
        .testAllPublicInstanceMethods(new ForwardingWrapperTester());
280
  }
281

282
  private <T> void assertFailure(
283
      Class<T> interfaceType,
284
      Function<T, ? extends T> wrapperFunction,
285
      String... expectedMessages) {
286
    try {
287
      tester.testForwarding(interfaceType, wrapperFunction);
288
    } catch (AssertionFailedError expected) {
289
      for (String message : expectedMessages) {
290
        assertThat(expected.getMessage()).contains(message);
291
      }
292
      return;
293
    }
294
    fail("expected failure not reported");
295
  }
296

297
  private class ForwardingRunnable implements Runnable {
298

299
    private final Runnable runnable;
300

301
    ForwardingRunnable(Runnable runnable) {
302
      this.runnable = runnable;
303
    }
304

305
    @Override
306
    public void run() {
307
      runnable.run();
308
    }
309

310
    @Override
311
    public String toString() {
312
      return runnable.toString();
313
    }
314
  }
315

316
  private interface Adder {
317
    int add(int a, int b);
318
  }
319

320
  private static class ForwardingArithmetic implements Arithmetic {
321
    private final Arithmetic arithmetic;
322

323
    public ForwardingArithmetic(Arithmetic arithmetic) {
324
      this.arithmetic = arithmetic;
325
    }
326

327
    @Override
328
    public int add(int a, int b) {
329
      return arithmetic.add(a, b);
330
    }
331

332
    @Override
333
    public int minus(int a, int b) {
334
      return arithmetic.minus(a, b);
335
    }
336

337
    @Override
338
    public String toString() {
339
      return arithmetic.toString();
340
    }
341
  }
342

343
  private static class FailsToForwardParameters implements Adder {
344
    private final Adder adder;
345

346
    FailsToForwardParameters(Adder adder) {
347
      this.adder = adder;
348
    }
349

350
    @Override
351
    public int add(int a, int b) {
352
      return adder.add(b, a);
353
    }
354

355
    @Override
356
    public String toString() {
357
      return adder.toString();
358
    }
359
  }
360

361
  private static class FailsToForwardReturnValue implements Adder {
362
    private final Adder adder;
363

364
    FailsToForwardReturnValue(Adder adder) {
365
      this.adder = adder;
366
    }
367

368
    @Override
369
    public int add(int a, int b) {
370
      return adder.add(a, b) + 1;
371
    }
372

373
    @Override
374
    public String toString() {
375
      return adder.toString();
376
    }
377
  }
378

379
  private static class FailsToPropagateException implements Adder {
380
    private final Adder adder;
381

382
    FailsToPropagateException(Adder adder) {
383
      this.adder = adder;
384
    }
385

386
    @Override
387
    public int add(int a, int b) {
388
      try {
389
        return adder.add(a, b);
390
      } catch (Exception e) {
391
        // swallow!
392
        return 0;
393
      }
394
    }
395

396
    @Override
397
    public String toString() {
398
      return adder.toString();
399
    }
400
  }
401

402
  public interface Arithmetic extends Adder {
403
    int minus(int a, int b);
404
  }
405

406
  private static class ForwardsToTheWrongMethod implements Arithmetic {
407
    private final Arithmetic arithmetic;
408

409
    ForwardsToTheWrongMethod(Arithmetic arithmetic) {
410
      this.arithmetic = arithmetic;
411
    }
412

413
    @Override
414
    public int minus(int a, int b) { // bad!
415
      return arithmetic.add(a, b);
416
    }
417

418
    @Override
419
    public int add(int a, int b) {
420
      return arithmetic.add(a, b);
421
    }
422

423
    @Override
424
    public String toString() {
425
      return arithmetic.toString();
426
    }
427
  }
428

429
  private interface ParameterTypesDifferent {
430
    void foo(
431
        String s,
432
        Runnable r,
433
        Number n,
434
        Iterable<?> it,
435
        boolean b,
436
        Equivalence<String> eq,
437
        Exception e,
438
        InputStream in,
439
        Comparable<?> c,
440
        Ordering<Integer> ord,
441
        Charset charset,
442
        TimeUnit unit,
443
        Class<?> cls,
444
        Joiner joiner,
445
        Pattern pattern,
446
        UnsignedInteger ui,
447
        UnsignedLong ul,
448
        StringBuilder sb,
449
        Predicate<?> pred,
450
        Function<?, ?> func,
451
        Object obj);
452
  }
453

454
  private static class ParameterTypesDifferentForwarder implements ParameterTypesDifferent {
455
    private final ParameterTypesDifferent delegate;
456

457
    public ParameterTypesDifferentForwarder(ParameterTypesDifferent delegate) {
458
      this.delegate = delegate;
459
    }
460

461
    @Override
462
    public void foo(
463
        String s,
464
        Runnable r,
465
        Number n,
466
        Iterable<?> it,
467
        boolean b,
468
        Equivalence<String> eq,
469
        Exception e,
470
        InputStream in,
471
        Comparable<?> c,
472
        Ordering<Integer> ord,
473
        Charset charset,
474
        TimeUnit unit,
475
        Class<?> cls,
476
        Joiner joiner,
477
        Pattern pattern,
478
        UnsignedInteger ui,
479
        UnsignedLong ul,
480
        StringBuilder sb,
481
        Predicate<?> pred,
482
        Function<?, ?> func,
483
        Object obj) {
484
      delegate.foo(
485
          s, r, n, it, b, eq, e, in, c, ord, charset, unit, cls, joiner, pattern, ui, ul, sb, pred,
486
          func, obj);
487
    }
488

489
    @Override
490
    public String toString() {
491
      return delegate.toString();
492
    }
493
  }
494

495
  public void testCovariantReturn() {
496
    new ForwardingWrapperTester()
497
        .testForwarding(
498
            Sub.class,
499
            new Function<Sub, Sub>() {
500
              @Override
501
              public Sub apply(Sub sub) {
502
                return new ForwardingSub(sub);
503
              }
504
            });
505
  }
506

507
  interface Base {
508
    CharSequence getId();
509
  }
510

511
  interface Sub extends Base {
512
    @Override
513
    String getId();
514
  }
515

516
  private static class ForwardingSub implements Sub {
517
    private final Sub delegate;
518

519
    ForwardingSub(Sub delegate) {
520
      this.delegate = delegate;
521
    }
522

523
    @Override
524
    public String getId() {
525
      return delegate.getId();
526
    }
527

528
    @Override
529
    public String toString() {
530
      return delegate.toString();
531
    }
532
  }
533

534
  private interface Equals {
535
    @Override
536
    boolean equals(@Nullable Object obj);
537

538
    @Override
539
    int hashCode();
540

541
    @Override
542
    String toString();
543
  }
544

545
  private static class NoDelegateToEquals implements Equals {
546

547
    private static Function<Equals, Equals> WRAPPER =
548
        new Function<Equals, Equals>() {
549
          @Override
550
          public NoDelegateToEquals apply(Equals delegate) {
551
            return new NoDelegateToEquals(delegate);
552
          }
553
        };
554

555
    private final Equals delegate;
556

557
    NoDelegateToEquals(Equals delegate) {
558
      this.delegate = delegate;
559
    }
560

561
    @Override
562
    public String toString() {
563
      return delegate.toString();
564
    }
565
  }
566

567
  public void testExplicitEqualsAndHashCodeNotDelegatedByDefault() {
568
    new ForwardingWrapperTester().testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
569
  }
570

571
  public void testExplicitEqualsAndHashCodeDelegatedWhenExplicitlyAsked() {
572
    try {
573
      new ForwardingWrapperTester()
574
          .includingEquals()
575
          .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
576
    } catch (AssertionFailedError expected) {
577
      return;
578
    }
579
    fail("Should have failed");
580
  }
581

582
  /** An interface for the 2 ways that a chaining call might be defined. */
583
  private interface ChainingCalls {
584
    // A method that is defined to 'return this'
585
    @CanIgnoreReturnValue
586
    ChainingCalls chainingCall();
587

588
    // A method that just happens to return a ChainingCalls object
589
    ChainingCalls nonChainingCall();
590
  }
591

592
  private static class ForwardingChainingCalls implements ChainingCalls {
593
    final ChainingCalls delegate;
594

595
    ForwardingChainingCalls(ChainingCalls delegate) {
596
      this.delegate = delegate;
597
    }
598

599
    @CanIgnoreReturnValue
600
    @Override
601
    public ForwardingChainingCalls chainingCall() {
602
      delegate.chainingCall();
603
      return this;
604
    }
605

606
    @Override
607
    public ChainingCalls nonChainingCall() {
608
      return delegate.nonChainingCall();
609
    }
610

611
    @Override
612
    public String toString() {
613
      return delegate.toString();
614
    }
615
  }
616

617
  public void testChainingCalls() {
618
    tester.testForwarding(
619
        ChainingCalls.class,
620
        new Function<ChainingCalls, ChainingCalls>() {
621
          @Override
622
          public ChainingCalls apply(ChainingCalls delegate) {
623
            return new ForwardingChainingCalls(delegate);
624
          }
625
        });
626
  }
627
}
628

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.