Add list accessor that can return random elements
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 30 Jul 2015 04:50:00 +0000 (06:50 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 30 Jul 2015 04:51:25 +0000 (06:51 +0200)
src/main/java/net/pterodactylus/sone/template/ListAccessor.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/test/java/net/pterodactylus/sone/template/ListAccessorTest.java [new file with mode: 0644]

diff --git a/src/main/java/net/pterodactylus/sone/template/ListAccessor.java b/src/main/java/net/pterodactylus/sone/template/ListAccessor.java
new file mode 100644 (file)
index 0000000..159a1ff
--- /dev/null
@@ -0,0 +1,30 @@
+package net.pterodactylus.sone.template;
+
+import java.util.List;
+import java.util.Random;
+
+import net.pterodactylus.util.template.Accessor;
+import net.pterodactylus.util.template.TemplateContext;
+
+/**
+ * {@link Accessor} implementation for {@link List}s that can return a random value from the list.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ListAccessor extends net.pterodactylus.util.template.ListAccessor {
+
+       private Random random = new Random();
+
+       @Override
+       public Object get(TemplateContext templateContext, Object object, String member) {
+               if ("random".equals(member)) {
+                       List<?> list = (List<?>) object;
+                       if (!list.isEmpty()) {
+                               return list.get(random.nextInt(list.size()));
+                       }
+                       return null;
+               }
+               return super.get(templateContext, object, member);
+       }
+
+}
index 06ebf8d..ef75b2c 100644 (file)
@@ -81,6 +81,7 @@ import net.pterodactylus.sone.template.IdentityAccessor;
 import net.pterodactylus.sone.template.ImageAccessor;
 import net.pterodactylus.sone.template.ImageLinkFilter;
 import net.pterodactylus.sone.template.JavascriptFilter;
+import net.pterodactylus.sone.template.ListAccessor;
 import net.pterodactylus.sone.template.ParserFilter;
 import net.pterodactylus.sone.template.PostAccessor;
 import net.pterodactylus.sone.template.ProfileAccessor;
@@ -264,6 +265,7 @@ public class WebInterface {
                templateContextFactory.addAccessor(Trust.class, new TrustAccessor());
                templateContextFactory.addAccessor(HTTPRequest.class, new HttpRequestAccessor());
                templateContextFactory.addAccessor(Profile.class, new ProfileAccessor(getCore()));
+               templateContextFactory.addAccessor(List.class, new ListAccessor());
                templateContextFactory.addFilter("date", new DateFilter());
                templateContextFactory.addFilter("html", new HtmlFilter());
                templateContextFactory.addFilter("replace", new ReplaceFilter());
diff --git a/src/test/java/net/pterodactylus/sone/template/ListAccessorTest.java b/src/test/java/net/pterodactylus/sone/template/ListAccessorTest.java
new file mode 100644 (file)
index 0000000..0c63aca
--- /dev/null
@@ -0,0 +1,50 @@
+package net.pterodactylus.sone.template;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.Matchers.sameInstance;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import net.pterodactylus.util.template.Accessor;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link ListAccessorTest}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ListAccessorTest {
+
+       private final Accessor accessor = new ListAccessor();
+
+       @Test
+       public void gettingARandomElementFromAnEmptyListReturnsNull() {
+               assertThat(accessor.get(null, Collections.emptyList(), "random"), nullValue());
+       }
+
+       @Test
+       public void gettingARandomElementFromAListOfOneWillReturnTheOneElement() {
+               Object object = new Object();
+               assertThat(accessor.get(null, Arrays.asList(object), "random"), sameInstance(object));
+       }
+
+       @Test
+       public void gettingRandomElementsFromAListTwoElementsWillReturnBothWithSomeProportion() {
+               Object first = new Object();
+               Object second = new Object();
+               List<?> objects = Arrays.asList(first, second);
+               int gotFirst = 0;
+               for (int i = 0; i < 10000; i++) {
+                       if (accessor.get(null, objects, "random") == first) {
+                               gotFirst++;
+                       }
+               }
+               assertThat(gotFirst, greaterThanOrEqualTo(4000));
+       }
+
+}