You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2018/11/02 11:16:22 UTC

[13/56] lucene-solr:jira/gradle: Add :solr:contrib:analytics module

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/legacy/facet/LegacyRangeFacetTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/legacy/facet/LegacyRangeFacetTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/legacy/facet/LegacyRangeFacetTest.java
new file mode 100644
index 0000000..329645e
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/legacy/facet/LegacyRangeFacetTest.java
@@ -0,0 +1,417 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.legacy.facet;
+
+
+import java.util.ArrayList;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class LegacyRangeFacetTest extends LegacyAbstractAnalyticsFacetTest {
+  static String fileName = "rangeFacets.txt";
+
+  public static final int INT = 71;
+  public static final int LONG = 36;
+  public static final int FLOAT = 93;
+  public static final int DOUBLE = 48;
+  public static final int DATE = 52;
+  public static final int STRING = 28;
+  public static final int NUM_LOOPS = 100;
+  
+  //INT
+  static ArrayList<ArrayList<Integer>> intLongTestStart; 
+  static ArrayList<ArrayList<Integer>> intDoubleTestStart; 
+  static ArrayList<ArrayList<Integer>> intDateTestStart; 
+  
+  //FLOAT
+  static ArrayList<ArrayList<Float>> floatLongTestStart; 
+  static ArrayList<ArrayList<Float>> floatDoubleTestStart; 
+  static ArrayList<ArrayList<Float>> floatDateTestStart; 
+  
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig-analytics.xml","schema-analytics.xml");
+    h.update("<delete><query>*:*</query></delete>");
+    
+    //INT
+    intLongTestStart = new ArrayList<>();
+    intDoubleTestStart = new ArrayList<>();
+    intDateTestStart = new ArrayList<>();
+    
+    //FLOAT
+    floatLongTestStart = new ArrayList<>();
+    floatDoubleTestStart = new ArrayList<>();
+    floatDateTestStart = new ArrayList<>();
+    
+    for (int j = 0; j < NUM_LOOPS; ++j) {
+      int i = j%INT;
+      long l = j%LONG;
+      float f = j%FLOAT;
+      double d = j%DOUBLE;
+      int dt = j%DATE;
+      int s = j%STRING;
+      assertU(adoc("id", "1000" + j, "int_id", "" + i, "long_ld", "" + l, "float_fd", "" + f, 
+          "double_dd", "" + d,  "date_dtd", (1000+dt) + "-01-01T23:59:59Z", "string_sd", "abc" + s));
+      //Longs
+      if (j-LONG<0) {
+        ArrayList<Integer> list1 = new ArrayList<>();
+        list1.add(i);
+        intLongTestStart.add(list1);
+        ArrayList<Float> list2 = new ArrayList<>();
+        list2.add(f);
+        floatLongTestStart.add(list2);
+      } else {
+        intLongTestStart.get((int)l).add(i);
+        floatLongTestStart.get((int)l).add(f);
+      }
+      //Doubles
+      if (j-DOUBLE<0) {
+        ArrayList<Integer> list1 = new ArrayList<>();
+        list1.add(i);
+        intDoubleTestStart.add(list1);
+        ArrayList<Float> list2 = new ArrayList<>();
+        list2.add(f);
+        floatDoubleTestStart.add(list2);
+      } else {
+        intDoubleTestStart.get((int)d).add(i);
+        floatDoubleTestStart.get((int)d).add(f);
+      }
+      //Dates
+      if (j-DATE<0) {
+        ArrayList<Integer> list1 = new ArrayList<>();
+        list1.add(i);
+        intDateTestStart.add(list1);
+        ArrayList<Float> list2 = new ArrayList<>();
+        list2.add(f);
+        floatDateTestStart.add(list2);
+      } else {
+        intDateTestStart.get(dt).add(i);
+        floatDateTestStart.get(dt).add(f);
+      }
+      
+      if (usually()) {
+        assertU(commit());  // to have several segments
+      }
+    }
+    
+    assertU(commit()); 
+    
+    setResponse(h.query(request(fileToStringArr(LegacyRangeFacetTest.class, fileName))));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void rangeTest() throws Exception {
+    
+    //Int Long
+    ArrayList<Long> intLong = getLongList("ri", "rangeFacets", "long_ld", "long", "count");
+    ArrayList<Long> intLongTest = calculateStat(transformLists(intLongTestStart, 5, 30, 5
+                                                        , false, true, false, false, false), "count");
+    assertEquals(getRawResponse(), intLong,intLongTest);
+    //Int Double
+    ArrayList<Double> intDouble = getDoubleList("ri", "rangeFacets", "double_dd", "double", "mean");
+    ArrayList<Double> intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7
+                                                          , false, false, true, false, true), "mean");
+    assertEquals(getRawResponse(), intDouble,intDoubleTest);
+    //Int Date
+    ArrayList<Long> intDate = getLongList("ri", "rangeFacets", "date_dtd", "long", "count");
+    ArrayList<Long> intDateTest = (ArrayList<Long>)calculateStat(transformLists(intDateTestStart, 7, 44, 7
+                                                      , false, true, false, true, true), "count");
+    assertEquals(getRawResponse(), intDate,intDateTest);
+    
+    //Float Long
+    ArrayList<Double> floatLong = getDoubleList("rf", "rangeFacets", "long_ld", "double", "median");
+    ArrayList<Double> floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4
+                                                          , false, true, true, true, true), "median");
+    assertEquals(getRawResponse(), floatLong,floatLongTest);
+    //Float Double
+    ArrayList<Long> floatDouble = getLongList("rf", "rangeFacets", "double_dd", "long", "count");
+    ArrayList<Long> floatDoubleTest = (ArrayList<Long>)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11
+                                                                     , false, false, false, true, false), "count");
+    assertEquals(getRawResponse(), floatDouble,floatDoubleTest);
+  }
+  
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void hardendRangeTest() throws Exception {
+    //Int Long
+    ArrayList<Double> intLong = getDoubleList("hi", "rangeFacets", "long_ld", "double", "sum");
+    ArrayList<Double> intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, 5
+                                                        , true, true, false, false, false), "sum");
+    assertEquals(getRawResponse(), intLong,intLongTest);
+    //Int Double
+    ArrayList<Double> intDouble = getDoubleList("hi", "rangeFacets", "double_dd", "double", "mean");
+    ArrayList<Double> intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, 7
+                                                          , true, false, true, false, true), "mean");
+    assertEquals(getRawResponse(), intDouble,intDoubleTest);
+    //Int Date
+    ArrayList<Long> intDate = getLongList("hi", "rangeFacets", "date_dtd", "long", "count");
+    ArrayList<Long> intDateTest = (ArrayList<Long>)calculateStat(transformLists(intDateTestStart, 7, 44, 7
+                                                      , true, true, false, true, true), "count");
+    assertEquals(getRawResponse(), intDate,intDateTest);
+    
+    //Float Long
+    ArrayList<Double> floatLong = getDoubleList("hf", "rangeFacets", "long_ld", "double", "median");
+    ArrayList<Double> floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, 4
+                                                          , true, true, true, true, true), "median");
+    assertEquals(getRawResponse(), floatLong,floatLongTest);
+    //Float Double
+    ArrayList<Long> floatDouble = getLongList("hf", "rangeFacets", "double_dd", "long", "count");
+    ArrayList<Long> floatDoubleTest = (ArrayList<Long>)calculateStat(transformLists(floatDoubleTestStart, 4, 47, 11
+                                                                     , true, false, false, true, false), "count");
+    assertEquals(getRawResponse(), floatDouble,floatDoubleTest);
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public void multiGapTest() throws Exception {
+    //Int Long
+    ArrayList<Double> intLong = getDoubleList("mi", "rangeFacets", "long_ld", "double", "sum");
+    ArrayList<Double> intLongTest = calculateNumberStat(transformLists(intLongTestStart, 5, 30, "4,2,6,3"
+                                                        , false, true, false, false, false), "sum");
+    assertEquals(getRawResponse(), intLong,intLongTest);
+    //Int Double
+    ArrayList<Double> intDouble = getDoubleList("mi", "rangeFacets", "double_dd", "double", "mean");
+    ArrayList<Double> intDoubleTest = calculateNumberStat(transformLists(intDoubleTestStart, 3, 39, "3,1,7"
+                                                          , false, false, true, false, true), "mean");
+    assertEquals(getRawResponse(), intDouble,intDoubleTest);
+    //Int Date
+    ArrayList<Long> intDate = getLongList("mi", "rangeFacets", "date_dtd", "long", "count");
+    ArrayList<Long> intDateTest = (ArrayList<Long>)calculateStat(transformLists(intDateTestStart, 7, 44, "2,7"
+                                                      , false, true, false, true, true), "count");
+    assertEquals(getRawResponse(), intDate,intDateTest);
+    
+    //Float Long
+    ArrayList<Double> floatLong = getDoubleList("mf", "rangeFacets", "long_ld", "double", "median");
+    ArrayList<Double> floatLongTest = calculateNumberStat(transformLists(floatLongTestStart, 0, 29, "1,4"
+                                                          , false, true, true, true, true), "median");;
+    assertEquals(getRawResponse(), floatLong,floatLongTest);
+    //Float Double
+    ArrayList<Long> floatDouble = getLongList("mf", "rangeFacets", "double_dd", "long", "count");
+    ArrayList<Long> floatDoubleTest = (ArrayList<Long>)calculateStat(transformLists(floatDoubleTestStart, 4, 47, "2,3,11"
+                                                          , false, false, false, true, false), "count");
+    assertEquals(getRawResponse(), floatDouble,floatDoubleTest);
+  }
+  
+  private <T> ArrayList<ArrayList<T>> transformLists(ArrayList<ArrayList<T>> listsStart, int start, int end, int gap
+      , boolean hardend, boolean incLow, boolean incUp, boolean incEdge, boolean incOut) {
+    int off = (end-start)%gap;
+    if (!hardend && off>0) {
+      end+=gap-off;
+    }
+
+    ArrayList<ArrayList<T>> lists = new ArrayList<>();
+    ArrayList<T> between = new ArrayList<>();
+    if (incLow && incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i; j<=i+gap && j<=end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start; i<listsStart.size() && i<=end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else if (incLow && !incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i; j<i+gap && j<end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start; i<listsStart.size() && i<end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else if (!incLow && incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i+1; j<=i+gap && j<=end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start+1; i<listsStart.size() && i<=end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i+1; j<i+gap && j<end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start+1; i<listsStart.size() && i<end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    }
+    
+    if (incEdge && !incLow && start>=0) {
+      lists.get(0).addAll(listsStart.get(start));
+      between.addAll(listsStart.get(start));
+    }
+    if (incEdge && !incUp && end<listsStart.size()) {
+      lists.get(lists.size()-1).addAll(listsStart.get(end));
+      between.addAll(listsStart.get(end));
+    }
+    ArrayList<T> before = new ArrayList<>();
+    ArrayList<T> after = new ArrayList<>();
+    if (incOut || !(incLow||incEdge)) {
+      for (int i = 0; i<=start; i++) {
+        before.addAll(listsStart.get(i));
+      }
+    } else {
+      for (int i = 0; i<start; i++) {
+        before.addAll(listsStart.get(i));
+      }
+    }
+    if (incOut || !(incUp||incEdge)) {
+      for (int i = end; i<listsStart.size(); i++) {
+        after.addAll(listsStart.get(i));
+      }
+    } 
+    else {
+      for (int i = end+1; i<listsStart.size(); i++) {
+        after.addAll(listsStart.get(i));
+      }
+    }
+    lists.add(before);
+    lists.add(after);
+    lists.add(between);
+    return lists;
+  }
+  
+  private <T> ArrayList<ArrayList<T>> transformLists(ArrayList<ArrayList<T>> listsStart, int start, int end, String gapString
+      , boolean hardend, boolean incLow, boolean incUp, boolean incEdge, boolean incOut) {
+    String[] stringGaps = gapString.split(",");
+    int[] gaps = new int[stringGaps.length];
+    for (int i = 0; i<gaps.length; i++) {
+      gaps[i] = Integer.parseInt(stringGaps[i]);
+    }
+    int bigGap = 0;
+    int last = gaps[gaps.length-1];
+    for (int i = 0; i<gaps.length-1; i++) {
+      bigGap += gaps[i];
+    }
+    int off = (end-start-bigGap)%last;
+    if (!hardend && off>0) {
+      end+=last-off;
+    }
+    
+    ArrayList<ArrayList<T>> lists = new ArrayList<>();
+    ArrayList<T> between = new ArrayList<>();
+    int gap = 0;
+    int gapCounter = 0;
+    if (incLow && incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        if (gapCounter<gaps.length) {
+          gap = gaps[gapCounter++];
+        }
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i; j<=i+gap && j<=end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start; i<listsStart.size() && i<=end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else if (incLow && !incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        if (gapCounter<gaps.length) {
+          gap = gaps[gapCounter++];
+        }
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i; j<i+gap && j<end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start; i<listsStart.size() && i<end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else if (!incLow && incUp) {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        if (gapCounter<gaps.length) {
+          gap = gaps[gapCounter++];
+        }
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i+1; j<=i+gap && j<=end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start+1; i<listsStart.size() && i<=end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    } else {
+      for (int i = start; i<end && i<listsStart.size(); i+=gap) {
+        if (gapCounter<gaps.length) {
+          gap = gaps[gapCounter++];
+        }
+        ArrayList<T> list = new ArrayList<>();
+        for (int j = i+1; j<i+gap && j<end && j<listsStart.size(); j++) {
+          list.addAll(listsStart.get(j));
+        }
+        lists.add(list);
+      }
+      for (int i = start+1; i<listsStart.size() && i<end; i++) {
+        between.addAll(listsStart.get(i));
+      }
+    }
+    
+    if (incEdge && !incLow && start>=0) {
+      lists.get(0).addAll(listsStart.get(start));
+      between.addAll(listsStart.get(start));
+    }
+    if (incEdge && !incUp && end<listsStart.size()) {
+      lists.get(lists.size()-1).addAll(listsStart.get(end));
+      between.addAll(listsStart.get(end));
+    }
+    ArrayList<T> before = new ArrayList<>();
+    ArrayList<T> after = new ArrayList<>();
+    if (incOut || !(incLow||incEdge)) {
+      for (int i = 0; i<=start; i++) {
+        before.addAll(listsStart.get(i));
+      }
+    } else {
+      for (int i = 0; i<start; i++) {
+        before.addAll(listsStart.get(i));
+      }
+    }
+    if (incOut || !(incUp||incEdge)) {
+      for (int i = end; i<listsStart.size(); i++) {
+        after.addAll(listsStart.get(i));
+      }
+    } 
+    else {
+      for (int i = end+1; i<listsStart.size(); i++) {
+        after.addAll(listsStart.get(i));
+      }
+    }
+    lists.add(before);
+    lists.add(after);
+    lists.add(between);
+    return lists;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingAnalyticsValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingAnalyticsValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingAnalyticsValueTest.java
new file mode 100644
index 0000000..3eb1e57
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingAnalyticsValueTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestAnalyticsValue;
+import org.junit.Test;
+
+public class CastingAnalyticsValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestAnalyticsValue val = new TestAnalyticsValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue("Object").setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList("Object").iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestAnalyticsValue();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueStreamTest.java
new file mode 100644
index 0000000..c96ad72
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueStreamTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestBooleanValueStream;
+import org.junit.Test;
+
+public class CastingBooleanValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestBooleanValueStream val = new TestBooleanValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(false, true, false);
+    Iterator<String> values = Arrays.asList("false", "true", "false").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestBooleanValueStream val = new TestBooleanValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(false, true, false);
+    Iterator<Object> values = Arrays.<Object>asList(Boolean.FALSE, Boolean.TRUE, Boolean.FALSE).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestBooleanValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueTest.java
new file mode 100644
index 0000000..e139f7e
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingBooleanValueTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestBooleanValue;
+import org.apache.solr.analytics.value.constant.ConstantBooleanValue;
+import org.junit.Test;
+
+public class CastingBooleanValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void stringCastingTest() {
+    TestBooleanValue val = new TestBooleanValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue(false).setExists(true);
+    assertEquals("false", casted.getString());
+    assertTrue(casted.exists());
+
+    val.setValue(true).setExists(true);
+    assertEquals("true", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() {
+    TestBooleanValue val = new TestBooleanValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue(false).setExists(true);
+    assertEquals(Boolean.FALSE, casted.getObject());
+    assertTrue(casted.exists());
+
+    val.setValue(true).setExists(true);
+    assertEquals(Boolean.TRUE, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void booleanStreamCastingTest() {
+    TestBooleanValue val = new TestBooleanValue();
+    
+    assertTrue(val instanceof BooleanValueStream);
+    BooleanValueStream casted = (BooleanValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamBooleans( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(false).setExists(true);
+    Iterator<Boolean> values = Arrays.asList(false).iterator();
+    casted.streamBooleans( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestBooleanValue val = new TestBooleanValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(false).setExists(true);
+    Iterator<String> values = Arrays.asList("false").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestBooleanValue val = new TestBooleanValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(false).setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(Boolean.FALSE).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    TestBooleanValue val = new TestBooleanValue(ExpressionType.CONST);
+    val.setValue(true).setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantBooleanValue);
+    assertEquals(true, ((ConstantBooleanValue)conv).getBoolean());
+
+    val = new TestBooleanValue(ExpressionType.FIELD);
+    val.setValue(true).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestBooleanValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue(true).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestBooleanValue(ExpressionType.REDUCTION);
+    val.setValue(true).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestBooleanValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue(true).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueStreamTest.java
new file mode 100644
index 0000000..e6659ea
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueStreamTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.time.Instant;
+import java.time.format.DateTimeParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestDateValueStream;
+import org.junit.Test;
+
+public class CastingDateValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void dateStreamCastingTest() throws DateTimeParseException {
+    Date date1 = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    Date date2 = Date.from(Instant.parse("1920-04-15T18:15:45Z"));
+    Date date3 = Date.from(Instant.parse("2012-11-30T20:30:15Z"));
+    TestDateValueStream val = new TestDateValueStream();
+    
+    assertTrue(val instanceof DateValueStream);
+    DateValueStream casted = (DateValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamDates( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues("1800-01-01T10:30:15Z", "1920-04-15T18:15:45Z", "2012-11-30T20:30:15Z");
+    Iterator<Date> values = Arrays.asList(date1, date2, date3).iterator();
+    casted.streamDates( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestDateValueStream val = new TestDateValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues("1800-01-01T10:30:15Z", "1920-04-15T18:15:45Z", "2012-11-30T20:30:15Z");
+    Iterator<String> values = Arrays.asList("1800-01-01T10:30:15Z", "1920-04-15T18:15:45Z", "2012-11-30T20:30:15Z").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() throws DateTimeParseException {
+    Date date1 = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    Date date2 = Date.from(Instant.parse("1920-04-15T18:15:45Z"));
+    Date date3 = Date.from(Instant.parse("2012-11-30T20:30:15Z"));
+    TestDateValueStream val = new TestDateValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues("1800-01-01T10:30:15Z", "1920-04-15T18:15:45Z", "2012-11-30T20:30:15Z");
+    Iterator<Object> values = Arrays.<Object>asList(date1, date2, date3).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestDateValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueTest.java
new file mode 100644
index 0000000..e0fd951
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDateValueTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.time.Instant;
+import java.time.format.DateTimeParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestDateValue;
+import org.apache.solr.analytics.value.constant.ConstantDateValue;
+import org.junit.Test;
+
+public class CastingDateValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void dateCastingTest() throws DateTimeParseException {
+    Date date = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof DateValue);
+    DateValue casted = (DateValue)val;
+
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    assertEquals(date, casted.getDate());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void stringCastingTest() {
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    assertEquals("1800-01-01T10:30:15Z", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() throws DateTimeParseException {
+    Date date = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    assertEquals(date, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void dateStreamCastingTest() throws DateTimeParseException {
+    Date date = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof DateValueStream);
+    DateValueStream casted = (DateValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamDates( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    Iterator<Date> values = Arrays.asList(date).iterator();
+    casted.streamDates( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    Iterator<String> values = Arrays.asList("1800-01-01T10:30:15Z").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() throws DateTimeParseException {
+    Date date = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    TestDateValue val = new TestDateValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(date).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() throws DateTimeParseException {
+    Date date = Date.from(Instant.parse("1800-01-01T10:30:15Z"));
+    
+    TestDateValue val = new TestDateValue(ExpressionType.CONST);
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantDateValue);
+    assertEquals(date, ((ConstantDateValue)conv).getDate());
+
+    val = new TestDateValue(ExpressionType.FIELD);
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDateValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDateValue(ExpressionType.REDUCTION);
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDateValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue("1800-01-01T10:30:15Z").setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueStreamTest.java
new file mode 100644
index 0000000..9de2636
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueStreamTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestDoubleValueStream;
+import org.junit.Test;
+
+public class CastingDoubleValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestDoubleValueStream val = new TestDoubleValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20.0, -3.32, 42.5);
+    Iterator<String> values = Arrays.asList("20.0", "-3.32", "42.5").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestDoubleValueStream val = new TestDoubleValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20.0, -3.32, 42.5);
+    Iterator<Object> values = Arrays.<Object>asList(20.0, -3.32, 42.5).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestDoubleValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueTest.java
new file mode 100644
index 0000000..410b96e
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingDoubleValueTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestDoubleValue;
+import org.apache.solr.analytics.value.constant.ConstantDoubleValue;
+import org.junit.Test;
+
+public class CastingDoubleValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void stringCastingTest() {
+    TestDoubleValue val = new TestDoubleValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue(20.0).setExists(true);
+    assertEquals("20.0", casted.getString());
+    assertTrue(casted.exists());
+
+    val.setValue(1234.0).setExists(true);
+    assertEquals("1234.0", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() {
+    TestDoubleValue val = new TestDoubleValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue(20.0).setExists(true);
+    assertEquals(20.0d, casted.getObject());
+    assertTrue(casted.exists());
+
+    val.setValue(1234.0).setExists(true);
+    assertEquals(1234.0d, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestDoubleValue val = new TestDoubleValue();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20.0).setExists(true);
+    Iterator<Double> values = Arrays.asList(20.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestDoubleValue val = new TestDoubleValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20.0).setExists(true);
+    Iterator<String> values = Arrays.asList("20.0").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestDoubleValue val = new TestDoubleValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20.0).setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(20.0d).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    TestDoubleValue val = new TestDoubleValue(ExpressionType.CONST);
+    val.setValue(12354.234).setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantDoubleValue);
+    assertEquals(12354.234, ((ConstantDoubleValue)conv).getDouble(), .0000001);
+
+    val = new TestDoubleValue(ExpressionType.FIELD);
+    val.setValue(12354.234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDoubleValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue(12354.234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDoubleValue(ExpressionType.REDUCTION);
+    val.setValue(12354.234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestDoubleValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue(12354.234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueStreamTest.java
new file mode 100644
index 0000000..ca79370
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueStreamTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestFloatValueStream;
+import org.junit.Test;
+
+public class CastingFloatValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestFloatValueStream val = new TestFloatValueStream();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20F, -3.32F, 42.5F);
+    Iterator<Double> values = Arrays.asList(20.0, -3.32, 42.5).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestFloatValueStream val = new TestFloatValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20F, -3.32F, 42.5F);
+    Iterator<String> values = Arrays.asList("20.0", "-3.32", "42.5").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestFloatValueStream val = new TestFloatValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20F, -3.32F, 42.5F);
+    Iterator<Object> values = Arrays.<Object>asList(20F, -3.32F, 42.5F).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestFloatValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueTest.java
new file mode 100644
index 0000000..b2f1e13
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingFloatValueTest.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestFloatValue;
+import org.apache.solr.analytics.value.constant.ConstantFloatValue;
+import org.junit.Test;
+
+public class CastingFloatValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void doubleCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof DoubleValue);
+    DoubleValue casted = (DoubleValue)val;
+
+    val.setValue(20F).setExists(true);
+    assertEquals(20.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+
+    val.setValue(1234F).setExists(true);
+    assertEquals(1234.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void stringCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue(20F).setExists(true);
+    assertEquals("20.0", casted.getString());
+    assertTrue(casted.exists());
+
+    val.setValue(1234F).setExists(true);
+    assertEquals("1234.0", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue(20F).setExists(true);
+    assertEquals(20F, casted.getObject());
+    assertTrue(casted.exists());
+
+    val.setValue(1234F).setExists(true);
+    assertEquals(1234F, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void floatStreamCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof FloatValueStream);
+    FloatValueStream casted = (FloatValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamFloats( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20F).setExists(true);
+    Iterator<Float> values = Arrays.asList(20F).iterator();
+    casted.streamFloats( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20F).setExists(true);
+    Iterator<Double> values = Arrays.asList(20.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20F).setExists(true);
+    Iterator<String> values = Arrays.asList("20.0").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestFloatValue val = new TestFloatValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20F).setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(20F).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    TestFloatValue val = new TestFloatValue(ExpressionType.CONST);
+    val.setValue(12354.234F).setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantFloatValue);
+    assertEquals(12354.234F, ((ConstantFloatValue)conv).getFloat(), .0000001);
+
+    val = new TestFloatValue(ExpressionType.FIELD);
+    val.setValue(12354.234F).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestFloatValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue(12354.234F).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestFloatValue(ExpressionType.REDUCTION);
+    val.setValue(12354.234F).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestFloatValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue(12354.234F).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueStreamTest.java
new file mode 100644
index 0000000..dac08ad
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueStreamTest.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestIntValueStream;
+import org.junit.Test;
+
+public class CastingIntValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void longStreamCastingTest() {
+    TestIntValueStream val = new TestIntValueStream();
+    
+    assertTrue(val instanceof LongValueStream);
+    LongValueStream casted = (LongValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamLongs( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20, -3, 42);
+    Iterator<Long> values = Arrays.asList(20L, -3L, 42L).iterator();
+    casted.streamLongs( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next().longValue(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void floatStreamCastingTest() {
+    TestIntValueStream val = new TestIntValueStream();
+    
+    assertTrue(val instanceof FloatValueStream);
+    FloatValueStream casted = (FloatValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamFloats( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20, -3, 42);
+    Iterator<Float> values = Arrays.asList(20F, -3F, 42F).iterator();
+    casted.streamFloats( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestIntValueStream val = new TestIntValueStream();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20, -3, 42);
+    Iterator<Double> values = Arrays.asList(20.0, -3.0, 42.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestIntValueStream val = new TestIntValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20, -3, 42);
+    Iterator<String> values = Arrays.asList("20", "-3", "42").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestIntValueStream val = new TestIntValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20, -3, 42);
+    Iterator<Object> values = Arrays.<Object>asList(20, -3, 42).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestIntValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueTest.java
new file mode 100644
index 0000000..dc6b69a
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingIntValueTest.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestIntValue;
+import org.apache.solr.analytics.value.constant.ConstantIntValue;
+import org.junit.Test;
+
+public class CastingIntValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void longCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof LongValue);
+    LongValue casted = (LongValue)val;
+
+    val.setValue(20).setExists(true);
+    assertEquals(20L, casted.getLong());
+    assertTrue(casted.exists());
+
+    val.setValue(1234).setExists(true);
+    assertEquals(1234L, casted.getLong());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void floatCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof FloatValue);
+    FloatValue casted = (FloatValue)val;
+
+    val.setValue(20).setExists(true);
+    assertEquals(20F, casted.getFloat(), .00001);
+    assertTrue(casted.exists());
+
+    val.setValue(1234).setExists(true);
+    assertEquals(1234F, casted.getFloat(), .00001);
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void doubleCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof DoubleValue);
+    DoubleValue casted = (DoubleValue)val;
+
+    val.setValue(20).setExists(true);
+    assertEquals(20.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+
+    val.setValue(1234).setExists(true);
+    assertEquals(1234.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void stringCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue(20).setExists(true);
+    assertEquals("20", casted.getString());
+    assertTrue(casted.exists());
+
+    val.setValue(1234).setExists(true);
+    assertEquals("1234", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue(20).setExists(true);
+    assertEquals(20, casted.getObject());
+    assertTrue(casted.exists());
+
+    val.setValue(1234).setExists(true);
+    assertEquals(1234, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void intStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof IntValueStream);
+    IntValueStream casted = (IntValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamInts( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<Integer> values = Arrays.asList(20).iterator();
+    casted.streamInts( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next().intValue(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void longStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof LongValueStream);
+    LongValueStream casted = (LongValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamLongs( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<Long> values = Arrays.asList(20L).iterator();
+    casted.streamLongs( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next().longValue(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void floatStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof FloatValueStream);
+    FloatValueStream casted = (FloatValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamFloats( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<Float> values = Arrays.asList(20F).iterator();
+    casted.streamFloats( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<Double> values = Arrays.asList(20.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<String> values = Arrays.asList("20").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestIntValue val = new TestIntValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20).setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(20).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    TestIntValue val = new TestIntValue(ExpressionType.CONST);
+    val.setValue(1234).setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantIntValue);
+    assertEquals(1234, ((ConstantIntValue)conv).getInt());
+
+    val = new TestIntValue(ExpressionType.FIELD);
+    val.setValue(1234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestIntValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue(1234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestIntValue(ExpressionType.REDUCTION);
+    val.setValue(1234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestIntValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue(1234).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueStreamTest.java
new file mode 100644
index 0000000..0988dbf
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueStreamTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestLongValueStream;
+import org.junit.Test;
+
+public class CastingLongValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestLongValueStream val = new TestLongValueStream();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20L, -3L, 42L);
+    Iterator<Double> values = Arrays.asList(20.0, -3.0, 42.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestLongValueStream val = new TestLongValueStream();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20L, -3L, 42L);
+    Iterator<String> values = Arrays.asList("20", "-3", "42").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestLongValueStream val = new TestLongValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues(20L, -3L, 42L);
+    Iterator<Object> values = Arrays.<Object>asList(20L, -3L, 42L).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestLongValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueTest.java
new file mode 100644
index 0000000..5d0f5cd
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingLongValueTest.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.AnalyticsValueStream.ExpressionType;
+import org.apache.solr.analytics.value.FillableTestValue.TestLongValue;
+import org.apache.solr.analytics.value.constant.ConstantLongValue;
+import org.junit.Test;
+
+public class CastingLongValueTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void doubleCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof DoubleValue);
+    DoubleValue casted = (DoubleValue)val;
+
+    val.setValue(20L).setExists(true);
+    assertEquals(20.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+
+    val.setValue(1234L).setExists(true);
+    assertEquals(1234.0, casted.getDouble(), .00001);
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void stringCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof StringValue);
+    StringValue casted = (StringValue)val;
+
+    val.setValue(20L).setExists(true);
+    assertEquals("20", casted.getString());
+    assertTrue(casted.exists());
+
+    val.setValue(1234L).setExists(true);
+    assertEquals("1234", casted.getString());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void objectCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof AnalyticsValue);
+    AnalyticsValue casted = (AnalyticsValue)val;
+
+    val.setValue(20L).setExists(true);
+    assertEquals(20L, casted.getObject());
+    assertTrue(casted.exists());
+
+    val.setValue(1234L).setExists(true);
+    assertEquals(1234L, casted.getObject());
+    assertTrue(casted.exists());
+  }
+
+  @Test
+  public void longStreamCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof LongValueStream);
+    LongValueStream casted = (LongValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamLongs( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20L).setExists(true);
+    Iterator<Long> values = Arrays.asList(20L).iterator();
+    casted.streamLongs( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next().longValue(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void doubleStreamCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof DoubleValueStream);
+    DoubleValueStream casted = (DoubleValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamDoubles( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20L).setExists(true);
+    Iterator<Double> values = Arrays.asList(20.0).iterator();
+    casted.streamDoubles( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value, .00001);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void stringStreamCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof StringValueStream);
+    StringValueStream casted = (StringValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamStrings( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20L).setExists(true);
+    Iterator<String> values = Arrays.asList("20").iterator();
+    casted.streamStrings( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestLongValue val = new TestLongValue();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setExists(false);
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValue(20L).setExists(true);
+    Iterator<Object> values = Arrays.<Object>asList(20L).iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    TestLongValue val = new TestLongValue(ExpressionType.CONST);
+    val.setValue(12341L).setExists(true);
+    AnalyticsValueStream conv = val.convertToConstant();
+    assertTrue(conv instanceof ConstantLongValue);
+    assertEquals(12341L, ((ConstantLongValue)conv).getLong());
+
+    val = new TestLongValue(ExpressionType.FIELD);
+    val.setValue(12341L).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestLongValue(ExpressionType.UNREDUCED_MAPPING);
+    val.setValue(12341L).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestLongValue(ExpressionType.REDUCTION);
+    val.setValue(12341L).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+
+    val = new TestLongValue(ExpressionType.REDUCED_MAPPING);
+    val.setValue(12341L).setExists(true);
+    conv = val.convertToConstant();
+    assertSame(val, conv);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0366b94/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingStringValueStreamTest.java
----------------------------------------------------------------------
diff --git a/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingStringValueStreamTest.java b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingStringValueStreamTest.java
new file mode 100644
index 0000000..8b1a229
--- /dev/null
+++ b/solr/contrib/analytics/src/test/java/org/apache/solr/analytics/value/CastingStringValueStreamTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.analytics.value;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.analytics.value.FillableTestValue.TestStringValueStream;
+import org.junit.Test;
+
+public class CastingStringValueStreamTest extends SolrTestCaseJ4 {
+
+  @Test
+  public void objectStreamCastingTest() {
+    TestStringValueStream val = new TestStringValueStream();
+    
+    assertTrue(val instanceof AnalyticsValueStream);
+    AnalyticsValueStream casted = (AnalyticsValueStream)val;
+    
+    // No values
+    val.setValues();
+    casted.streamObjects( value -> {
+      assertTrue("There should be no values to stream", false);
+    });
+
+    // Multiple Values
+    val.setValues("abc", "def", "ghi");
+    Iterator<Object> values = Arrays.<Object>asList("abc", "def", "ghi").iterator();
+    casted.streamObjects( value -> {
+      assertTrue(values.hasNext());
+      assertEquals(values.next(), value);
+    });
+    assertFalse(values.hasNext());
+  }
+  
+  @Test
+  public void constantConversionTest() {
+    AnalyticsValueStream val = new TestStringValueStream();
+    assertSame(val, val.convertToConstant());
+  }
+}