Skip to content

Commit f98d592

Browse files
committed
Added remainder of common unit tests (one test ignored)
1 parent 1f520c9 commit f98d592

File tree

1 file changed

+191
-1
lines changed

1 file changed

+191
-1
lines changed

src/test/java/io/engagingspaces/vertx/dataloader/DataLoaderTest.java

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.vertx.ext.unit.junit.RunTestOnContext;
2323
import io.vertx.ext.unit.junit.VertxUnitRunner;
2424
import org.junit.Before;
25+
import org.junit.Ignore;
2526
import org.junit.Rule;
2627
import org.junit.Test;
2728
import org.junit.runner.RunWith;
@@ -33,6 +34,7 @@
3334

3435
import static org.awaitility.Awaitility.await;
3536
import static org.hamcrest.Matchers.*;
37+
import static org.junit.Assert.assertArrayEquals;
3638
import static org.junit.Assert.assertThat;
3739

3840
/**
@@ -531,13 +533,201 @@ public void should_Accept_objects_with_a_complex_key() {
531533
assertThat(future2.result(), equalTo(key1));
532534
}
533535

536+
@Test
537+
public void should_Clear_objects_with_complex_key() {
538+
ArrayList<Collection> loadCalls = new ArrayList<>();
539+
DataLoaderOptions options = DataLoaderOptions.create().setCacheKeyFunction(getJsonObjectCacheMapFn());
540+
DataLoader<JsonObject, Integer> identityLoader = idLoader(options, loadCalls);
541+
542+
JsonObject key1 = new JsonObject().put("id", 123);
543+
JsonObject key2 = new JsonObject().put("id", 123);
544+
545+
Future<Integer> future1 = identityLoader.load(key1);
546+
identityLoader.dispatch();
547+
548+
await().until(future1::isComplete);
549+
identityLoader.clear(key2); // clear equivalent object key
550+
551+
Future<Integer> future2 = identityLoader.load(key1);
552+
identityLoader.dispatch();
553+
554+
await().until(future2::isComplete);
555+
assertThat(loadCalls, equalTo(Arrays.asList(Collections.singletonList(key1), Collections.singletonList(key1))));
556+
assertThat(future1.result(), equalTo(key1));
557+
assertThat(future2.result(), equalTo(key1));
558+
}
559+
560+
@Test
561+
public void should_Accept_objects_with_different_order_of_keys() {
562+
ArrayList<Collection> loadCalls = new ArrayList<>();
563+
DataLoaderOptions options = DataLoaderOptions.create().setCacheKeyFunction(getJsonObjectCacheMapFn());
564+
DataLoader<JsonObject, Integer> identityLoader = idLoader(options, loadCalls);
565+
566+
JsonObject key1 = new JsonObject().put("a", 123).put("b", 321);
567+
JsonObject key2 = new JsonObject().put("b", 321).put("a", 123);
568+
569+
// Fetches as expected
570+
571+
Future<Integer> future1 = identityLoader.load(key1);
572+
Future<Integer> future2 = identityLoader.load(key2);
573+
identityLoader.dispatch();
574+
575+
await().until(() -> future1.isComplete() && future2.isComplete());
576+
assertThat(loadCalls, equalTo(Collections.singletonList(Collections.singletonList(key1))));
577+
assertThat(loadCalls.size(), equalTo(1));
578+
assertThat(future1.result(), equalTo(key1));
579+
assertThat(future2.result(), equalTo(key1));
580+
}
581+
582+
@Test
583+
public void should_Allow_priming_the_cache_with_an_object_key() {
584+
ArrayList<Collection> loadCalls = new ArrayList<>();
585+
DataLoaderOptions options = DataLoaderOptions.create().setCacheKeyFunction(getJsonObjectCacheMapFn());
586+
DataLoader<JsonObject, JsonObject> identityLoader = idLoader(options, loadCalls);
587+
588+
JsonObject key1 = new JsonObject().put("id", 123);
589+
JsonObject key2 = new JsonObject().put("id", 123);
590+
591+
identityLoader.prime(key1, key1);
592+
593+
Future<JsonObject> future1 = identityLoader.load(key1);
594+
Future<JsonObject> future2 = identityLoader.load(key2);
595+
identityLoader.dispatch();
596+
597+
await().until(() -> future1.isComplete() && future2.isComplete());
598+
assertThat(loadCalls, equalTo(Collections.emptyList()));
599+
assertThat(future1.result(), equalTo(key1));
600+
assertThat(future2.result(), equalTo(key1));
601+
}
602+
603+
@Test
604+
public void should_Accept_a_custom_cache_map_implementation() {
605+
CustomCacheMap customMap = new CustomCacheMap();
606+
ArrayList<Collection> loadCalls = new ArrayList<>();
607+
DataLoaderOptions options = DataLoaderOptions.create().setCacheMap(customMap);
608+
DataLoader<String, String> identityLoader = idLoader(options, loadCalls);
609+
610+
// Fetches as expected
611+
612+
Future future1 = identityLoader.load("a");
613+
Future future2 = identityLoader.load("b");
614+
CompositeFuture composite = identityLoader.dispatch();
615+
616+
await().until((Callable<Boolean>) composite::isComplete);
617+
assertThat(future1.result(), equalTo("a"));
618+
assertThat(future2.result(), equalTo("b"));
619+
620+
assertThat(loadCalls, equalTo(Collections.singletonList(Arrays.asList("a", "b"))));
621+
assertArrayEquals(customMap.stash.keySet().toArray(), Arrays.asList("a", "b").toArray());
622+
623+
Future future3 = identityLoader.load("c");
624+
Future future2a = identityLoader.load("b");
625+
composite = identityLoader.dispatch();
626+
627+
await().until((Callable<Boolean>) composite::isComplete);
628+
assertThat(future3.result(), equalTo("c"));
629+
assertThat(future2a.result(), equalTo("b"));
630+
631+
assertThat(loadCalls, equalTo(Arrays.asList(Arrays.asList("a", "b"), Collections.singletonList("c"))));
632+
assertArrayEquals(customMap.stash.keySet().toArray(), Arrays.asList("a", "b", "c").toArray());
633+
634+
// Supports clear
635+
636+
identityLoader.clear("b");
637+
assertArrayEquals(customMap.stash.keySet().toArray(), Arrays.asList("a", "c").toArray());
638+
639+
Future future2b = identityLoader.load("b");
640+
composite = identityLoader.dispatch();
641+
642+
await().until((Callable<Boolean>) composite::isComplete);
643+
assertThat(future2b.result(), equalTo("b"));
644+
assertThat(loadCalls, equalTo(Arrays.asList(Arrays.asList("a", "b"),
645+
Collections.singletonList("c"), Collections.singletonList("b"))));
646+
assertArrayEquals(customMap.stash.keySet().toArray(), Arrays.asList("a", "c", "b").toArray());
647+
648+
// Supports clear all
649+
650+
identityLoader.clearAll();
651+
assertArrayEquals(customMap.stash.keySet().toArray(), Collections.emptyList().toArray());
652+
}
653+
654+
// It is resilient to job queue ordering
655+
656+
@Test
657+
public void should_Batch_loads_occurring_within_futures() {
658+
ArrayList<Collection> loadCalls = new ArrayList<>();
659+
DataLoader<String, String> identityLoader = idLoader(DataLoaderOptions.create(), loadCalls);
660+
661+
Future.<String>future().setHandler(rh -> {
662+
identityLoader.load("a");
663+
Future.future().setHandler(rh2 -> {
664+
identityLoader.load("b");
665+
Future.future().setHandler(rh3 -> {
666+
identityLoader.load("c");
667+
Future.future().setHandler(rh4 ->
668+
identityLoader.load("d")).complete();
669+
}).complete();
670+
}).complete();
671+
}).complete();
672+
CompositeFuture composite = identityLoader.dispatch();
673+
674+
await().until((Callable<Boolean>) composite::isComplete);
675+
assertThat(loadCalls, equalTo(
676+
Collections.singletonList(Arrays.asList("a", "b", "c", "d"))));
677+
}
678+
679+
@Test
680+
@Ignore
681+
public void should_Call_a_loader_from_a_loader() {
682+
// TODO Provide implementation with Futures
683+
}
684+
685+
// Helper methods
686+
534687
private static CacheKey<JsonObject> getJsonObjectCacheMapFn() {
535688
return key -> key.stream()
536-
.sorted()
537689
.map(entry -> entry.getKey() + ":" + entry.getValue())
690+
.sorted()
538691
.collect(Collectors.joining());
539692
}
540693

694+
public class CustomCacheMap implements CacheMap<String, Object> {
695+
696+
public Map<String, Object> stash;
697+
698+
public CustomCacheMap() {
699+
stash = new LinkedHashMap<>();
700+
}
701+
702+
@Override
703+
public boolean containsKey(String key) {
704+
return stash.containsKey(key);
705+
}
706+
707+
@Override
708+
public Object get(String key) {
709+
return stash.get(key);
710+
}
711+
712+
@Override
713+
public CacheMap<String, Object> set(String key, Object value) {
714+
stash.put(key, value);
715+
return this;
716+
}
717+
718+
@Override
719+
public CacheMap<String, Object> delete(String key) {
720+
stash.remove(key);
721+
return this;
722+
}
723+
724+
@Override
725+
public CacheMap<String, Object> clear() {
726+
stash.clear();
727+
return this;
728+
}
729+
}
730+
541731
@SuppressWarnings("unchecked")
542732
private static <K, V> DataLoader<K, V> idLoader(DataLoaderOptions options, List<Collection> loadCalls) {
543733
return new DataLoader<>(keys -> {

0 commit comments

Comments
 (0)