1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.rapiddweller.benerator.test;
28
29 import com.rapiddweller.benerator.Generator;
30 import com.rapiddweller.benerator.engine.DefaultBeneratorContext;
31 import com.rapiddweller.benerator.primitive.number.AbstractNonNullNumberGenerator;
32 import com.rapiddweller.benerator.wrapper.ProductWrapper;
33 import com.rapiddweller.common.ArrayFormat;
34 import com.rapiddweller.common.ArrayUtil;
35 import com.rapiddweller.common.BeanUtil;
36 import com.rapiddweller.common.CollectionUtil;
37 import com.rapiddweller.common.Converter;
38 import com.rapiddweller.common.IOUtil;
39 import com.rapiddweller.common.Resettable;
40 import com.rapiddweller.common.Validator;
41 import com.rapiddweller.common.collection.ObjectCounter;
42 import com.rapiddweller.common.converter.ToStringConverter;
43 import com.rapiddweller.common.validator.UniqueValidator;
44 import com.rapiddweller.model.data.Entity;
45
46 import java.util.Collection;
47 import java.util.HashSet;
48 import java.util.Map;
49 import java.util.Set;
50 import java.util.concurrent.atomic.AtomicInteger;
51
52 import static org.junit.Assert.assertEquals;
53 import static org.junit.Assert.assertFalse;
54 import static org.junit.Assert.assertNotNull;
55 import static org.junit.Assert.assertNull;
56 import static org.junit.Assert.assertTrue;
57 import static org.junit.Assert.fail;
58
59
60
61
62
63
64
65
66 public abstract class GeneratorTest extends ModelTest {
67
68 private final Converter<Object, String> formatter = new ToStringConverter();
69
70
71
72
73
74
75
76
77
78
79
80 public <T extends Generator<U>, U> T initialize(T generator) {
81 generator.init(context);
82 return generator;
83 }
84
85
86
87
88
89
90 public void close(Generator<?> generator) {
91 IOUtil.close(generator);
92 }
93
94
95
96
97
98
99
100 public void setCurrentProduct(Object product, String productName) {
101 ((DefaultBeneratorContext) context).setCurrentProduct(new ProductWrapper<>(product), productName);
102 }
103
104
105
106
107
108
109
110 @SuppressWarnings({"unchecked", "rawtypes"})
111 public void printProducts(Generator<?> generator, int n) {
112 ProductWrapperoductWrapper.html#ProductWrapper">ProductWrapper wrapper = new ProductWrapper();
113 for (int i = 0; i < n; i++) {
114 ProductWrapper<?> tmp = generator.generate(wrapper);
115 if (tmp == null) {
116 System.out.println("<>");
117 } else {
118 System.out.println(formatter.convert(tmp.unwrap()));
119 }
120 }
121 }
122
123
124
125
126
127
128
129
130
131 public static <T> Map<T, AtomicInteger> countProducts(Generator<T> generator, int n) {
132 ObjectCounter<T> counter = new ObjectCounter<>(Math.min(n, 1000));
133 ProductWrapper<T> wrapper = new ProductWrapper<>();
134 for (int i = 0; i < n; i++) {
135 wrapper = generator.generate(wrapper);
136 if (wrapper == null) {
137 fail("Generator unavailable after " + i + " of " + n + " invocations");
138 } else {
139 counter.count(wrapper.unwrap());
140 }
141 }
142 return counter.getCounts();
143 }
144
145
146
147
148
149
150
151
152 protected static <T> void assertEqualArrays(T expected, T actual) {
153 ArrayFormat format = new ArrayFormat();
154 assertTrue("Expected " + format.format(expected) + ", found: " + format.format(actual),
155 ArrayUtil.equals(expected, actual));
156 }
157
158
159
160
161
162
163
164
165
166 @SafeVarargs
167 protected static <T> Helper expectGeneratedSequence(Generator<T> generator, T... products) {
168 expectGeneratedSequenceOnce(generator, products);
169 generator.reset();
170 expectGeneratedSequenceOnce(generator, products);
171 return new Helper(generator);
172 }
173
174
175
176
177
178
179
180
181
182
183 @SafeVarargs
184 protected final <T> Helper expectGeneratedSet(Generator<T> generator, int invocations, T... products) {
185 expectGeneratedSetOnce(generator, invocations, products);
186 generator.reset();
187 expectGeneratedSetOnce(generator, invocations, products);
188 return new Helper(generator);
189 }
190
191
192
193
194
195
196
197
198
199 @SafeVarargs
200 protected final <T> Helper expectUniquelyGeneratedSet(Generator<T> generator, T... products) {
201 expectUniquelyGeneratedSetOnce(generator, products);
202 generator.reset();
203 expectUniquelyGeneratedSetOnce(generator, products);
204 return new Helper(generator);
205 }
206
207
208
209
210
211
212
213
214
215 protected <T> Helper expectUniqueProducts(Generator<T> generator, int n) {
216 expectUniqueProductsOnce(generator, n);
217 generator.reset();
218 expectUniqueProductsOnce(generator, n);
219 return new Helper(generator);
220 }
221
222
223
224
225
226
227
228
229
230
231 @SuppressWarnings({"unchecked", "rawtypes"})
232 protected <T> Helper expectGenerations(Generator<T> generator, int n, Validator... validators) {
233 expectGenerationsOnce(generator, n, validators);
234 generator.reset();
235 for (Validator<?> validator : validators) {
236 if (validator instanceof Resettable) {
237 ((Resettable) validator).reset();
238 }
239 }
240 expectGenerationsOnce(generator, n, validators);
241 return new Helper(generator);
242 }
243
244
245
246
247
248
249
250
251
252 protected <T> Helper expectUniqueGenerations(Generator<T> generator, int n) {
253 expectUniqueGenerationsOnce(generator, n);
254 generator.reset();
255 expectUniqueGenerationsOnce(generator, n);
256 return new Helper(generator);
257 }
258
259
260
261
262
263
264
265
266
267
268 protected <T extends Comparable<T>> void expectRange(Generator<T> generator, int n, T min, T max) {
269 expectRangeOnce(generator, n, min, max);
270 generator.reset();
271 expectRangeOnce(generator, n, min, max);
272 new Helper(generator);
273 }
274
275
276
277
278
279
280
281
282 protected <T> String format(T product) {
283 return ToStringConverter.convert(product, "[null]");
284 }
285
286
287
288
289
290
291 @SuppressWarnings({"rawtypes", "unchecked"})
292 public static void assertUnavailable(Generator<?> generator) {
293 assertNull("Generator " + generator + " is expected to be unavailable", generator.generate(new ProductWrapper()));
294 }
295
296
297
298
299
300
301 public static void assertAvailable(Generator<?> generator) {
302 assertAvailable("Generator " + generator + " is expected to be available", generator);
303 }
304
305
306
307
308
309
310
311 @SuppressWarnings({"rawtypes", "unchecked"})
312 public static void assertAvailable(String message, Generator<?> generator) {
313 assertNotNull(message, generator.generate(new ProductWrapper()));
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 @SafeVarargs
331 public static <T extends Number> void checkEqualDistribution(
332 Class<? extends AbstractNonNullNumberGenerator<T>> generatorClass, T min, T max, T granularity,
333 int iterations, double tolerance, T... expectedValues) {
334 Set<T> expectedSet = CollectionUtil.toSet(expectedValues);
335 checkDistribution(generatorClass, min, max, granularity, iterations, true, tolerance, expectedSet);
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350 public static <T extends Number> void checkEqualDistribution(
351 Class<? extends AbstractNonNullNumberGenerator<T>> generatorClass, T min, T max, T granularity,
352 int iterations, double tolerance, Set<T> expectedSet) {
353 checkDistribution(generatorClass, min, max, granularity, iterations, true, tolerance, expectedSet);
354 }
355
356 private static <T extends Number> void checkDistribution(
357 Class<? extends AbstractNonNullNumberGenerator<T>> generatorClass, T min, T max, T granularity,
358 int iterations, boolean equalDistribution, double tolerance, Set<T> expectedSet) {
359 AbstractNonNullNumberGenerator<T> generator = BeanUtil.newInstance(generatorClass);
360 generator.setMin(min);
361 generator.setMax(max);
362 generator.setGranularity(granularity);
363 ObjectCounter<T> counter = new ObjectCounter<>(expectedSet != null ? expectedSet.size() : 10);
364 ProductWrapper<T> wrapper = new ProductWrapper<>();
365 for (int i = 0; i < iterations; i++) {
366 counter.count(generator.generate(wrapper).unwrap());
367 }
368 checkDistribution(counter, equalDistribution, tolerance, expectedSet);
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382 public static <E> void checkEqualDistribution(
383 Generator<E> generator, int iterations, double tolerance, Set<E> expectedSet) {
384 checkDistribution(generator, iterations, true, tolerance, expectedSet);
385 }
386
387
388
389
390
391
392
393
394
395 public static <T> void checkProductSet(Generator<T> generator, int iterations, Set<T> expectedSet) {
396 checkDistribution(generator, iterations, false, 0, expectedSet);
397 }
398
399 private static <T> void checkDistribution(Generator<T> generator,
400 int iterations, boolean equalDistribution, double tolerance, Set<T> expectedSet) {
401 ObjectCounter<T> counter = new ObjectCounter<>(expectedSet != null ? expectedSet.size() : 10);
402 ProductWrapper<T> wrapper = new ProductWrapper<>();
403 for (int i = 0; i < iterations; i++) {
404 counter.count(generator.generate(wrapper).unwrap());
405 }
406 checkDistribution(counter, equalDistribution, tolerance, expectedSet);
407 }
408
409
410
411
412
413
414
415
416 @SuppressWarnings({"rawtypes", "unchecked"})
417 protected static void expectRelativeWeights(Generator<?> generator, int iterations, Object... expectedValueWeightPairs) {
418 ObjectCounter<Object> counter = new ObjectCounter<>(expectedValueWeightPairs.length / 2);
419 ProductWrapperoductWrapper.html#ProductWrapper">ProductWrapper wrapper = new ProductWrapper();
420 for (int i = 0; i < iterations; i++) {
421 wrapper = generator.generate(wrapper);
422 if (wrapper == null) {
423 fail("Generator unavailable after " + i + " of " + iterations + " invocations");
424 } else {
425 counter.count(wrapper.unwrap());
426 }
427 }
428 Set<Object> productSet = counter.objectSet();
429 double totalExpectedWeight = 0;
430 for (int i = 1; i < expectedValueWeightPairs.length; i += 2) {
431 totalExpectedWeight += ((Number) expectedValueWeightPairs[i]).doubleValue();
432 }
433
434 for (int i = 0; i < expectedValueWeightPairs.length; i += 2) {
435 Object value = expectedValueWeightPairs[i];
436 if (totalExpectedWeight == 0) {
437 totalExpectedWeight = 0.00000001;
438 }
439 double expectedWeight = ((Number) expectedValueWeightPairs[i + 1]).doubleValue() / totalExpectedWeight;
440 if (expectedWeight > 0) {
441 assertTrue("Generated set does not contain value " + value, productSet.contains(value));
442 double measuredWeight = counter.getRelativeCount(value);
443 assertTrue("For value '" + value + "', weight " + expectedWeight + " is expected, but it is " + measuredWeight,
444 Math.abs(measuredWeight - expectedWeight) / expectedWeight < 0.15);
445 } else {
446 assertFalse("Generated contains value " + value + " though it has zero weight", productSet.contains(value));
447 }
448 }
449 }
450
451
452
453
454
455
456
457
458
459
460
461 public static <E> void checkEqualDistribution(Collection<E> collection, double tolerance, Set<E> expectedSet) {
462 checkDistribution(collection, true, tolerance, expectedSet);
463 }
464
465 private static <E> void checkDistribution(Collection<E> collection,
466 boolean equalDistribution, double tolerance, Set<E> expectedSet) {
467 ObjectCounter<E> counter = new ObjectCounter<>(expectedSet != null ? expectedSet.size() : 10);
468 for (E object : collection) {
469 counter.count(object);
470 }
471 checkDistribution(counter, equalDistribution, tolerance, expectedSet);
472 }
473
474
475
476
477
478
479
480
481
482
483
484 public static <E> void checkEqualDistribution(
485 ObjectCounter<E> counter, double tolerance, Set<E> expectedSet) {
486 checkDistribution(counter, true, tolerance, expectedSet);
487 }
488
489 private static <E> void checkDistribution(
490 ObjectCounter<E> counter, boolean equalDistribution, double tolerance, Set<E> expectedSet) {
491 if (equalDistribution) {
492 assertTrue("Distribution is not equal: " + counter, counter.equalDistribution(tolerance));
493 }
494 if (expectedSet != null) {
495 assertEquals(expectedSet, counter.objectSet());
496 }
497 }
498
499
500
501
502 public static class Helper {
503 private final Generator<?> generator;
504
505
506
507
508
509
510 public Helper(Generator<?> generator) {
511 this.generator = generator;
512 }
513
514
515
516
517 public void withCeasedAvailability() {
518 try {
519 assertUnavailable(generator);
520 } finally {
521 generator.close();
522 }
523 }
524
525
526
527
528 public void withContinuedAvailability() {
529 assertAvailable(generator);
530 }
531 }
532
533
534
535
536
537
538
539
540
541
542 @SafeVarargs
543 protected static <T> void expectGeneratedSequenceOnce(Generator<T> generator, T... products) {
544 int count = 0;
545 ProductWrapper<T> wrapper = new ProductWrapper<>();
546 for (T expectedProduct : products) {
547 wrapper = generator.generate(wrapper);
548 assertNotNull("Generator is unavailable after generating " + count + " of " + products.length + " products: " + generator, wrapper);
549 T generatedProduct = wrapper.unwrap();
550 if (generatedProduct.getClass().isArray()) {
551 assertEqualArrays(expectedProduct, generatedProduct);
552 } else {
553 assertEquals(expectedProduct, generatedProduct);
554 }
555 count++;
556 }
557 }
558
559 @SafeVarargs
560 private <T> void expectGeneratedSetOnce(Generator<T> generator, int invocations, T... expectedProducts) {
561 Set<T> expectedSet = CollectionUtil.toSet(expectedProducts);
562 Set<T> observedSet = new HashSet<>(expectedProducts.length);
563 ProductWrapper<T> wrapper = new ProductWrapper<>();
564 for (int i = 0; i < invocations; i++) {
565 wrapper = generator.generate(wrapper);
566 assertNotNull("Generator has gone unavailable. " +
567 "Generated only " + i + " of " + expectedProducts.length + " expected values: " + observedSet,
568 wrapper);
569 T generation = wrapper.unwrap();
570 if (logger.isDebugEnabled()) {
571 logger.debug("created " + format(generation));
572 }
573 assertTrue("The generated value '" + format(generation) + "' was not in the expected set: " + expectedSet,
574 expectedSet.contains(generation));
575 observedSet.add(generation);
576 }
577 assertEquals(expectedSet, observedSet);
578 }
579
580 @SafeVarargs
581 private <T> void expectUniquelyGeneratedSetOnce(Generator<T> generator, T... expectedProducts) {
582 Set<T> expectedSet = CollectionUtil.toSet(expectedProducts);
583 UniqueValidator<Object> validator = new UniqueValidator<>();
584 ProductWrapper<T> wrapper = new ProductWrapper<>();
585 for (int i = 0; i < expectedProducts.length; i++) {
586 wrapper = generator.generate(wrapper);
587 assertNotNull("Generator has gone unavailable after " + i + " products, " +
588 "expected " + expectedProducts.length + " products. ", wrapper);
589 T product = wrapper.unwrap();
590 if (logger.isDebugEnabled()) {
591 logger.debug("created " + format(product));
592 }
593 assertTrue("Product is not unique: " + product, validator.valid(product));
594 assertTrue("The generated value '" + format(product) + "' was not in the expected set: "
595 + format(expectedSet), expectedSet.contains(product));
596 }
597 }
598
599 private <T> void expectUniqueProductsOnce(Generator<T> generator, int n) {
600 UniqueValidator<T> validator = new UniqueValidator<>();
601 ProductWrapper<T> wrapper = new ProductWrapper<>();
602 for (int i = 0; i < n; i++) {
603 wrapper = generator.generate(wrapper);
604 assertNotNull("Generator is not available: " + generator, wrapper);
605 T product = wrapper.unwrap();
606 logger.debug("created: " + format(product));
607 assertTrue("Product is not unique: " + product, validator.valid(product));
608 }
609 }
610
611 @SafeVarargs
612 private <T> void expectGenerationsOnce(Generator<T> generator, int n, Validator<T>... validators) {
613 ProductWrapper<T> wrapper = new ProductWrapper<>();
614 for (int i = 0; i < n; i++) {
615 wrapper = generator.generate(wrapper);
616 assertNotNull("Generator has gone unavailable before creating the required number of products, " +
617 "required " + n + " but was " + i,
618 wrapper);
619 T product = wrapper.unwrap();
620 if (logger.isDebugEnabled()) {
621 logger.debug("created " + format(product));
622 }
623 for (Validator<T> validator : validators) {
624 assertTrue("The generated value '" + format(product) + "' is not valid according to " + validator +
625 ", failed after " + i + " generations",
626 validator.valid(product));
627 }
628 }
629 }
630
631 @SafeVarargs
632 private <T> void expectUniqueGenerationsOnce(Generator<T> generator, int n, Validator<T>... validators) {
633 UniqueValidator<T> validator = new UniqueValidator<>();
634 ProductWrapper<T> wrapper = new ProductWrapper<>();
635 for (int i = 0; i < n; i++) {
636 wrapper = generator.generate(wrapper);
637 assertNotNull("Generator has gone unavailable before creating the required number of products ",
638 wrapper);
639 T product = wrapper.unwrap();
640 logger.debug("created " + format(product));
641 assertTrue("The generated value '" + format(product) + "' is not unique. Generator is " + generator,
642 validator.valid(product));
643 }
644 }
645
646
647
648
649
650
651
652
653
654
655 protected <T extends Comparable<T>> void expectRangeOnce(Generator<T> generator, int n, T min, T max) {
656 ProductWrapper<T> wrapper = new ProductWrapper<>();
657 for (int i = 0; i < n; i++) {
658 wrapper = generator.generate(wrapper);
659 assertNotNull(wrapper);
660 T product = wrapper.unwrap();
661 assertTrue("Generated value (" + product + ") is less than the configured minimum (" + min + ")", min.compareTo(product) <= 0);
662 assertTrue("Generated value (" + product + ") is greater than the configured maximum (" + max + ")", max.compareTo(product) >= 0);
663 }
664 }
665
666
667
668
669
670
671
672 public static void assertComponents(Entity entity, Object... nameValuePairs) {
673 for (int i = 0; i < nameValuePairs.length; i += 2) {
674 String name = (String) nameValuePairs[i];
675 Object expected = nameValuePairs[i + 1];
676 Object actual = entity.getComponent(name);
677 assertEquals("Unexpected value for component '" + name + "':", expected, actual);
678 }
679 }
680
681 }