blob: 4955e40d1139697d562628d4656c45ca5695fa4f [file] [log] [blame]
/*
* 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.fineract.cn.individuallending.internal.service;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Myrle Krantz
*/
@RunWith(Parameterized.class)
public class RateCollectorsTest {
final static private BigDecimal pointOne = BigDecimal.valueOf(0.1);
private static class TestCase {
private final String description;
private Collection<BigDecimal> values;
private BigDecimal expectedCompound;
private BigDecimal expectedGeometricMean;
private int significantDigits;
TestCase(final String description) {
this.description = description;
}
TestCase values(final Collection<BigDecimal> newVal) {
values = newVal;
return this;
}
TestCase compound(final BigDecimal newVal) {
expectedCompound = newVal;
return this;
}
TestCase geometricMean(final BigDecimal newVal) {
expectedGeometricMean = newVal;
return this;
}
TestCase significantDigits(final int newVal) {
significantDigits = newVal;
return this;
}
@Override
public String toString() {
return "TestCase{" +
"description='" + description + '\'' +
'}';
}
}
@Parameterized.Parameters
public static Collection testCases() {
final Collection<TestCase> ret = new ArrayList<>();
ret.add(baseCase());
ret.add(lotsaPointOnesCase());
ret.add(slightlyMoreComplexCase());
return ret;
}
private static TestCase baseCase() {
return new TestCase("baseCase")
.values(Collections.singletonList(pointOne))
.significantDigits(1)
.compound(pointOne)
.geometricMean(pointOne);
}
private static TestCase lotsaPointOnesCase() {
return new TestCase("lotsaPointOnesCase")
.values(Stream
.iterate(pointOne, x -> pointOne)
.limit(10).collect(Collectors.toList()))
.significantDigits(3)
.compound(BigDecimal.valueOf(1.594))
.geometricMean(pointOne.setScale(3, BigDecimal.ROUND_HALF_EVEN));
}
private static TestCase slightlyMoreComplexCase() {
return new TestCase("slightlyMoreComplexCase")
.values(Arrays.asList(BigDecimal.valueOf(0.2), BigDecimal.valueOf(0.06), BigDecimal.valueOf(0.01)))
.significantDigits(4)
.compound(BigDecimal.valueOf(0.2847))
.geometricMean(BigDecimal.valueOf(0.0871));
}
private final TestCase testCase;
public RateCollectorsTest(final TestCase testCase)
{
this.testCase = testCase;
}
@Test
public void geometricMean() throws Exception {
Assert.assertEquals(testCase.expectedGeometricMean, testCase.values.stream().collect(RateCollectors.geometricMean(testCase.significantDigits)));
}
@Test
public void compound()
{
Assert.assertEquals(testCase.expectedCompound, testCase.values.stream().collect(RateCollectors.compound(testCase.significantDigits)));
}
@Test
public void compoundAndGeometricMeanCompatible()
{
final BigDecimal geometricMean = testCase.values.stream()
.collect(RateCollectors.geometricMean(testCase.significantDigits));
final BigDecimal compoundingOfGeometricMean = Stream
.iterate(geometricMean, x -> geometricMean)
.limit(testCase.values.size())
.collect(RateCollectors.compound(testCase.significantDigits));
Assert.assertEquals(testCase.expectedCompound, compoundingOfGeometricMean);
}
@Test
public void compoundViaParalletStream()
{
Assert.assertEquals(testCase.expectedCompound, testCase.values.parallelStream().collect(RateCollectors.compound(testCase.significantDigits)));
}
@Test
public void geometricMeanViaParalletStream()
{
Assert.assertEquals(testCase.expectedGeometricMean, testCase.values.parallelStream().collect(RateCollectors.geometricMean(testCase.significantDigits)));
}
}