@Test
public void testMerge() throws CardinalityMergeException
{

    int numToMerge = 10;
    int tippingPoint = 100;
    int cardinality = 1000;
    CountThenEstimate[] ctes = new CountThenEstimate[numToMerge];
    for (int i = 0; i < numToMerge; i++)
    {
        ctes[i] = new CountThenEstimate(tippingPoint, AdaptiveCounting.Builder.obyCount(100000));
        for (int j = 0; j < tippingPoint - 1; j++)
        {
            ctes[i].offer(Math.random());
        }
    }
    int expectedCardinality = numToMerge * (tippingPoint - 1);
    long mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
    double error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
    assertEquals(0.01, error, 0.01);
    for (int i = 0; i < numToMerge / 2; i++)
    {
        for (int j = tippingPoint - 1; j < cardinality; j++)
        {
            ctes[i].offer(Math.random());
        }
    }
    expectedCardinality = (numToMerge / 2) * (cardinality + tippingPoint - 1);
    mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
    error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
    assertEquals(0.01, error, 0.01);
    for (int i = numToMerge / 2; i < numToMerge; i++)
    {
        for (int j = tippingPoint - 1; j < cardinality; j++)
        {
            ctes[i].offer(Math.random());
        }
    }
    expectedCardinality = numToMerge * cardinality;
    mergedEstimate = CountThenEstimate.mergeEstimators(ctes).cardinality();
    error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
    assertEquals(0.01, error, 0.01);
}