/*****************************************************************************
* Limpet - the Lightweight InforMation ProcEssing Toolkit
* http://limpet.info
*
* (C) 2015-2016, Deep Blue C Technologies Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html)
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
package info.limpet.data;
import static javax.measure.unit.NonSI.HOUR;
import static javax.measure.unit.NonSI.KILOMETERS_PER_HOUR;
import static javax.measure.unit.NonSI.KILOMETRES_PER_HOUR;
import static javax.measure.unit.NonSI.MINUTE;
import static javax.measure.unit.SI.KILO;
import static javax.measure.unit.SI.METRE;
import static javax.measure.unit.SI.METRES_PER_SECOND;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import info.limpet.ICollection;
import info.limpet.ICommand;
import info.limpet.IContext;
import info.limpet.IOperation;
import info.limpet.IQuantityCollection;
import info.limpet.IStore;
import info.limpet.IStoreItem;
import info.limpet.ITemporalQuantityCollection;
import info.limpet.QuantityRange;
import info.limpet.data.csv.CsvParser;
import info.limpet.data.impl.MockContext;
import info.limpet.data.impl.ObjectCollection;
import info.limpet.data.impl.QuantityCollection;
import info.limpet.data.impl.TemporalQuantityCollection;
import info.limpet.data.impl.samples.SampleData;
import info.limpet.data.impl.samples.StockTypes;
import info.limpet.data.impl.samples.StockTypes.NonTemporal.AngleDegrees;
import info.limpet.data.impl.samples.StockTypes.Temporal.SpeedKts;
import info.limpet.data.impl.samples.TemporalLocation;
import info.limpet.data.operations.AddLayerOperation;
import info.limpet.data.operations.CollectionComplianceTests;
import info.limpet.data.operations.GenerateDummyDataOperation;
import info.limpet.data.operations.UnitConversionOperation;
import info.limpet.data.operations.admin.CopyCsvToClipboardAction;
import info.limpet.data.operations.admin.CreateLocationAction;
import info.limpet.data.operations.admin.CreateSingletonGenerator;
import info.limpet.data.operations.admin.ExportCsvToFileAction;
import info.limpet.data.operations.admin.OperationsLibrary;
import info.limpet.data.operations.arithmetic.AddQuantityOperation;
import info.limpet.data.operations.arithmetic.DeleteCollectionOperation;
import info.limpet.data.operations.arithmetic.DivideQuantityOperation;
import info.limpet.data.operations.arithmetic.MultiplyQuantityOperation;
import info.limpet.data.operations.arithmetic.SimpleMovingAverageOperation;
import info.limpet.data.operations.arithmetic.SubtractQuantityOperation;
import info.limpet.data.operations.arithmetic.UnitaryMathOperation;
import info.limpet.data.operations.spatial.BearingBetweenTracksOperation;
import info.limpet.data.store.StoreGroup;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.measure.Measurable;
import javax.measure.Measure;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Angle;
import javax.measure.quantity.Dimensionless;
import javax.measure.quantity.Duration;
import javax.measure.quantity.Length;
import javax.measure.quantity.Quantity;
import javax.measure.quantity.Velocity;
import javax.measure.unit.Unit;
import junit.framework.Assert;
import org.easymock.EasyMock;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class TestOperations
{
private IContext context = new MockContext();
@Rule
public final ExpectedException thrown = ExpectedException.none();
@SuppressWarnings(
{"rawtypes", "unchecked"})
@Test
public void testInterpolateTests()
{
// place to store results data
StoreGroup store = new SampleData().getData(10);
// ok, let's try one that works
List<IStoreItem> selection = new ArrayList<IStoreItem>();
// ///////////////
// TEST INVALID PERMUTATIONS
// ///////////////
ICollection speedGood1 = (ICollection) store.get(SampleData.SPEED_ONE);
ICollection speedGood2 = (ICollection) store.get(SampleData.SPEED_TWO);
ICollection speedLonger =
(ICollection) store.get(SampleData.SPEED_THREE_LONGER);
selection.add(speedGood1);
selection.add(speedLonger);
Collection<ICommand<ICollection>> actions =
new AddQuantityOperation().actionsFor(selection, store, context);
assertEquals("correct number of actions returned", 1, actions.size());
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
actions = new AddQuantityOperation().actionsFor(selection, store, context);
assertEquals("correct number of actions returned", 2, actions.size());
ICommand<?> addAction = actions.iterator().next();
assertNotNull("found action", addAction);
}
@Test
public void testTrig()
{
// prepare some data
SpeedKts speedData = new StockTypes.Temporal.SpeedKts("speed", null);
speedData.add(100, 23);
speedData.add(200, 44);
AngleDegrees angleData =
new StockTypes.NonTemporal.AngleDegrees("degs", null);
angleData.add(200d);
angleData.add(123d);
StockTypes.Temporal.AngleDegrees temporalAngleData =
new StockTypes.Temporal.AngleDegrees("degs", null);
temporalAngleData.add(1000, 200d);
temporalAngleData.add(3000, 123d);
temporalAngleData.add(4000, 13d);
List<ICollection> selection = new ArrayList<ICollection>();
StoreGroup store = new StoreGroup();
HashMap<String, List<IOperation<?>>> ops =
OperationsLibrary.getOperations();
List<IOperation<?>> arith = ops.get(OperationsLibrary.ARITHMETIC);
// ok, now find the trig op
Iterator<IOperation<?>> iter = arith.iterator();
IOperation<ICollection> sinOp = null;
IOperation<ICollection> cosOp = null;
while (iter.hasNext())
{
IOperation<?> thisO = (IOperation<?>) iter.next();
if (thisO instanceof UnitaryMathOperation)
{
UnitaryMathOperation umo = (UnitaryMathOperation) thisO;
if (umo.getName().equals("Sin"))
{
sinOp = umo;
}
if (umo.getName().equals("Cos"))
{
cosOp = umo;
}
}
}
assertNotNull("check we found it", sinOp);
// ok, try it with empty data
Collection<ICommand<ICollection>> validOps =
sinOp.actionsFor(selection, null, null);
assertEquals("null for empty selection", 0, validOps.size());
// add some speed data
selection.add(speedData);
// ok, try it with empty data
validOps = sinOp.actionsFor(selection, store, null);
assertEquals("empty for invalid selection", 0, validOps.size());
// add some valid data
selection.add(angleData);
// ok, try it with empty data
validOps = sinOp.actionsFor(selection, store, null);
assertEquals("empty for invalid selection", 0, validOps.size());
// ok, try it with empty data
validOps = cosOp.actionsFor(selection, store, null);
assertEquals(" cos also empty for invalid selection", 0, validOps.size());
// and remove the speed data
selection.remove(speedData);
// ok, try it with empty data
validOps = sinOp.actionsFor(selection, store, context);
assertEquals("non-empty for valid selection", 1, validOps.size());
ICommand<ICollection> theOp = validOps.iterator().next();
theOp.execute();
assertEquals("has new dataset", 1, store.size());
ICollection output = theOp.getOutputs().iterator().next();
// check the size
assertEquals("correct size", 2, output.getValuesCount());
// check data type
assertTrue("isn't temporal", !output.isTemporal());
assertTrue("is quantity", output.isQuantity());
// ok, try it temporal data
selection.remove(angleData);
selection.add(temporalAngleData);
validOps = sinOp.actionsFor(selection, store, context);
assertEquals("non-empty for valid selection", 1, validOps.size());
theOp = validOps.iterator().next();
theOp.execute();
assertEquals("has new dataset", 2, store.size());
output = theOp.getOutputs().iterator().next();
// check the size
assertEquals("correct size", 3, output.getValuesCount());
// check data type
assertTrue("isn't temporal", output.isTemporal());
}
@Test
public void testAppliesTo()
{
// the units for this measurement
Unit<Velocity> kmh = KILO(METRE).divide(HOUR).asType(Velocity.class);
Unit<Velocity> kmm = KILO(METRE).divide(MINUTE).asType(Velocity.class);
Unit<Length> m = METRE.asType(Length.class);
// the target collection
QuantityCollection<Velocity> speedGood1 =
new QuantityCollection<Velocity>("Speed 1", null, kmh);
QuantityCollection<Velocity> speedGood2 =
new QuantityCollection<Velocity>("Speed 2", null, kmh);
QuantityCollection<Velocity> speedLonger =
new QuantityCollection<Velocity>("Speed 3", null, kmh);
QuantityCollection<Velocity> speedDiffUnits =
new QuantityCollection<Velocity>("Speed 4", null, kmm);
QuantityCollection<Length> len1 =
new QuantityCollection<Length>("Length 1", null, m);
TemporalQuantityCollection<Velocity> temporalSpeed1 =
new TemporalQuantityCollection<Velocity>("Speed 5", null, kmh);
TemporalQuantityCollection<Velocity> temporalSpeed2 =
new TemporalQuantityCollection<Velocity>("Speed 6", null, kmh);
ObjectCollection<String> string1 = new ObjectCollection<>("strings 1");
ObjectCollection<String> string2 = new ObjectCollection<>("strings 2");
for (int i = 1; i <= 10; i++)
{
// create a measurement
double thisSpeed = i * 2;
Measurable<Velocity> speedVal1 = Measure.valueOf(thisSpeed, kmh);
Measurable<Velocity> speedVal2 = Measure.valueOf(thisSpeed * 2, kmh);
Measurable<Velocity> speedVal3 = Measure.valueOf(thisSpeed / 2, kmh);
Measurable<Velocity> speedVal4 = Measure.valueOf(thisSpeed / 2, kmm);
Measurable<Length> lenVal1 = Measure.valueOf(thisSpeed / 2, m);
// store the measurements
speedGood1.add(speedVal1);
speedGood2.add(speedVal2);
speedLonger.add(speedVal3);
speedDiffUnits.add(speedVal4);
temporalSpeed1.add(i, speedVal2);
temporalSpeed2.add(i, speedVal3);
len1.add(lenVal1);
string1.add(i + " ");
string2.add(i + "a ");
}
Measurable<Velocity> max = temporalSpeed1.max();
System.out.println(max);
Measurable<Velocity> min = temporalSpeed1.min();
System.out.println(min);
QuantityRange<Velocity> range = temporalSpeed1.getRange();
System.out.println(range);
Measurable<Velocity> speedVal3a = Measure.valueOf(2, kmh);
speedLonger.add(speedVal3a);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
CollectionComplianceTests testOp = new CollectionComplianceTests();
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
assertTrue("all same dim", testOp.allEqualDimensions(selection));
assertTrue("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertTrue("all quantities", testOp.allQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
assertFalse("all groups",testOp.allGroups(selection));
assertFalse("all Temporal or singleton",testOp.allTemporalOrSingleton(selection));
assertTrue("Longest collection lenght", testOp.getLongestCollectionLength(selection) > 0);
StoreGroup track1 = new StoreGroup("Track 1");
selection.add(track1);
assertFalse("all childrens are tracks",testOp.allChildrenAreTracks(selection));
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
selection.add(speedDiffUnits);
assertTrue("all same dim", testOp.allEqualDimensions(selection));
assertFalse("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertTrue("all quantities", testOp.allQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
selection.add(len1);
assertFalse("all same dim", testOp.allEqualDimensions(selection));
assertFalse("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertTrue("all quantities", testOp.allQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
selection.add(speedLonger);
assertTrue("all same dim", testOp.allEqualDimensions(selection));
assertTrue("all same units", testOp.allEqualUnits(selection));
assertFalse("all same length", testOp.allEqualLength(selection));
assertTrue("all quantities", testOp.allQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
selection.clear();
selection.add(temporalSpeed1);
selection.add(temporalSpeed2);
assertTrue("all same dim", testOp.allEqualDimensions(selection));
assertTrue("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertTrue("all quantities", testOp.allQuantity(selection));
assertTrue("all temporal", testOp.allTemporal(selection));
selection.clear();
selection.add(temporalSpeed1);
selection.add(string1);
assertFalse("all same dim", testOp.allEqualDimensions(selection));
assertFalse("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertFalse("all quantities", testOp.allQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
selection.clear();
selection.add(string1);
selection.add(string1);
assertFalse("all same dim", testOp.allEqualDimensions(selection));
assertFalse("all same units", testOp.allEqualUnits(selection));
assertTrue("all same length", testOp.allEqualLength(selection));
assertTrue("all non quantities", testOp.allNonQuantity(selection));
assertFalse("all temporal", testOp.allTemporal(selection));
// ok, let's try one that works
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
StoreGroup store = new StoreGroup();
assertEquals("store empty", 0, store.size());
@SuppressWarnings(
{"unchecked", "rawtypes"})
Collection<ICommand<ICollection>> actions =
new AddQuantityOperation().actionsFor(selection, store, context);
assertEquals("correct number of actions returned", 1, actions.size());
ICommand<?> addAction = actions.iterator().next();
addAction.execute();
assertEquals("new collection added to store", 1, store.size());
ICollection firstItem = (ICollection) store.iterator().next();
ICommand<?> precedent = firstItem.getPrecedent();
assertNotNull("has precedent", precedent);
assertEquals("Correct name",
"Add numeric values in provided series (indexed)", precedent.getName());
List<? extends IStoreItem> inputs = precedent.getInputs();
assertEquals("Has both precedents", 2, inputs.size());
Iterator<? extends IStoreItem> iIter = inputs.iterator();
while (iIter.hasNext())
{
ICollection thisC = (ICollection) iIter.next();
List<ICommand<?>> deps = thisC.getDependents();
assertEquals("has a depedent", 1, deps.size());
Iterator<ICommand<?>> dIter = deps.iterator();
while (dIter.hasNext())
{
ICommand<?> iCommand = dIter.next();
assertEquals("Correct dependent", precedent, iCommand);
}
}
List<? extends IStoreItem> outputs = precedent.getOutputs();
assertEquals("Has both dependents", 1, outputs.size());
Iterator<? extends IStoreItem> oIter = outputs.iterator();
while (oIter.hasNext())
{
ICollection thisC = (ICollection) oIter.next();
ICommand<?> dep = thisC.getPrecedent();
assertNotNull("has a depedent", dep);
assertEquals("Correct dependent", precedent, dep);
}
}
@Test
public void testDimensionlessMultiply()
{
// place to store results data
StoreGroup store = new SampleData().getData(10);
// ok, let's try one that works
List<IStoreItem> selection = new ArrayList<IStoreItem>();
// ///////////////
// TEST INVALID PERMUTATIONS
// ///////////////
ICollection speedGood1 = (ICollection) store.get(SampleData.SPEED_ONE);
ICollection speedGood2 = (ICollection) store.get(SampleData.SPEED_TWO);
ICollection speedIrregular =
(ICollection) store.get(SampleData.SPEED_IRREGULAR2);
ICollection string1 = (ICollection) store.get(SampleData.STRING_ONE);
ICollection len1 = (ICollection) store.get(SampleData.LENGTH_ONE);
ICollection factor =
(ICollection) store.get(SampleData.FLOATING_POINT_FACTOR);
selection.clear();
selection.add(speedGood1);
selection.add(string1);
Collection<ICommand<IStoreItem>> commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("invalid collections - not both quantities", 0, commands
.size());
selection.clear();
selection.add(speedGood1);
selection.add(len1);
commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid collections - both quantities", 1, commands.size());
selection.clear();
selection.add(speedGood1);
selection.add(speedGood2);
store.clear();
assertEquals("store empty", 0, store.size());
commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid collections - both speeds", 1, commands.size());
// //////////////////////////
// now test valid collections
// /////////////////////////
selection.clear();
selection.add(speedGood1);
selection.add(factor);
assertEquals("store empty", 0, store.size());
commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid collections - one is singleton", 1, commands.size());
ICommand<IStoreItem> command = commands.iterator().next();
// test actions has single item: "Multiply series by constant"
assertEquals("correct name", "Multiply series", command.getName());
// apply action
command.execute();
// test store has a new item in it
assertEquals("store not empty", 1, store.size());
ICollection newS =
(ICollection) store
.get("Product of Speed One Time, Floating point factor");
// test results is same length as thisSpeed
assertEquals("correct size", 10, newS.getValuesCount());
selection.clear();
selection.add(speedGood1);
selection.add(factor);
store.clear();
assertEquals("store empty", 0, store.size());
commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid collections - one is singleton", 1, commands.size());
selection.clear();
selection.add(speedGood1);
selection.add(speedIrregular);
store.clear();
assertEquals("store empty", 0, store.size());
commands =
new MultiplyQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid collections - one is singleton", 1, commands.size());
command = commands.iterator().next();
command.execute();
ICollection output = (ICollection) command.getOutputs().iterator().next();
assertTrue(output.isTemporal());
assertTrue(output.isQuantity());
assertEquals("Correct len", Math.max(speedGood1.getValuesCount(),
speedIrregular.getValuesCount()), output.getValuesCount());
}
@Test
@SuppressWarnings("unchecked")
public void testUnitConversion()
{
// place to store results data
IStore store = new SampleData().getData(10);
List<ICollection> selection = new ArrayList<ICollection>(3);
// speed one defined in m/s
ICollection speedGood1 = (ICollection) store.get(SampleData.SPEED_ONE);
selection.add(speedGood1);
// test incompatible target unit
Collection<ICommand<ICollection>> commands =
new UnitConversionOperation(METRE)
.actionsFor(selection, store, context);
assertEquals("target unit not same dimension as input", 0, commands.size());
// test valid target unit
commands =
new UnitConversionOperation(KILOMETRES_PER_HOUR).actionsFor(selection,
store, context);
assertEquals("valid unit dimensions", 1, commands.size());
ICommand<ICollection> command = commands.iterator().next();
// apply action
command.execute();
ICollection newS =
(ICollection) store.get("Speed One Time converted to km/h");
assertNotNull(newS);
command.dataChanged(newS);
// test results is same length as thisSpeed
assertEquals("correct size", 10, newS.getValuesCount());
assertTrue("is temporal", newS.isTemporal());
// check that operation isn't offered if the dataset is already in
// that type
commands =
new UnitConversionOperation(METRES_PER_SECOND).actionsFor(selection,
store, context);
assertEquals("already in destination units", 0, commands.size());
IQuantityCollection<?> inputSpeed = (IQuantityCollection<?>) speedGood1;
Measurable<Velocity> firstInputSpeed =
(Measurable<Velocity>) inputSpeed.getValues().get(0);
IQuantityCollection<?> outputSpeed = (IQuantityCollection<?>) newS;
Measurable<Velocity> outputMEas =
(Measurable<Velocity>) outputSpeed.getValues().get(0);
double firstOutputSpeed =
outputMEas.doubleValue((Unit<Velocity>) outputSpeed.getUnits());
UnitConverter oc =
inputSpeed.getUnits().getConverterTo(KILOMETERS_PER_HOUR);
assertEquals(oc.convert(firstInputSpeed
.doubleValue((Unit<Velocity>) inputSpeed.getUnits())), firstOutputSpeed,0);
}
@Test
public void testTemporalMovingAverage()
{
// place to store results data
IStore store = new SampleData().getData(10);
List<ICollection> selection = new ArrayList<>();
@SuppressWarnings("unchecked")
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
selection.add(speedGood1);
int windowSize=3;
Collection<ICommand<ICollection>> commands =
new SimpleMovingAverageOperation(windowSize).actionsFor(selection,
store, context);
assertEquals(1, commands.size());
ICommand<ICollection> command = commands.iterator().next();
// apply action
command.execute();
@SuppressWarnings("unchecked")
IQuantityCollection<Velocity> newS =
(IQuantityCollection<Velocity>) store
.get("Moving average of Speed One Time");
assertNotNull(newS);
// test results is same length as thisSpeed
assertEquals("correct size", 10, newS.getValuesCount());
// calculate sum of input values [0..windowSize-1]
double sum = 0;
for (int i = 0; i < windowSize; i++)
{
Measurable<Velocity> inputQuantity = speedGood1.getValues().get(i);
sum += inputQuantity.doubleValue(speedGood1.getUnits());
}
double average = sum / windowSize;
// compare to output value [windowSize-1]
Measurable<Velocity> simpleMovingAverage =
newS.getValues().get(windowSize - 1);
assertEquals(average, simpleMovingAverage.doubleValue(newS.getUnits()), 0);
}
@Test
public void testSimpleMovingAverage()
{
// place to store results data
IStore store = new SampleData().getData(10);
List<ICollection> selection = new ArrayList<>();
@SuppressWarnings("unchecked")
QuantityCollection<Length> lengthOne =
(QuantityCollection<Length>) store.get(SampleData.LENGTH_ONE);
selection.add(lengthOne);
int windowSize=3;
Collection<ICommand<ICollection>> commands =
new SimpleMovingAverageOperation(windowSize).actionsFor(selection,
store, context);
assertEquals(1, commands.size());
ICommand<ICollection> command = commands.iterator().next();
// apply action
command.execute();
@SuppressWarnings("unchecked")
IQuantityCollection<Velocity> newS =
(IQuantityCollection<Velocity>) store
.get("Moving average of Length One non-Time");
assertNotNull(newS);
// test results is same length as thisSpeed
assertEquals("correct size", 10, newS.getValuesCount());
// calculate sum of input values [0..windowSize-1]
double sum = 0;
for (int i = 0; i < windowSize; i++)
{
Measurable<Length> inputQuantity = lengthOne.getValues().get(i);
sum += inputQuantity.doubleValue(lengthOne.getUnits());
}
double average = sum / windowSize;
// compare to output value [windowSize-1]
Measurable<Velocity> simpleMovingAverage =
newS.getValues().get(windowSize - 1);
assertEquals(average, simpleMovingAverage.doubleValue(newS.getUnits()), 0);
}
@Test
@SuppressWarnings(
{"unchecked"})
public void testAddition()
{
StoreGroup store = new SampleData().getData(10);
// test invalid dimensions
ITemporalQuantityCollection<Velocity> speedGood1 =
(ITemporalQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
IQuantityCollection<Velocity> speedGood2 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_TWO);
IQuantityCollection<Velocity> newS =
(IQuantityCollection<Velocity>) store
.get("Sum of Speed One Time, Speed Two Time");
assertNotNull(newS);
assertEquals("correct size", 10, newS.getValuesCount());
// assert same unit
assertEquals(newS.getUnits(), speedGood1.getUnits());
double firstDifference =
newS.getValues().get(0).doubleValue(newS.getUnits());
double speed1firstValue =
speedGood1.getValues().get(0).doubleValue(speedGood1.getUnits());
double speed2firstValue =
speedGood2.getValues().get(0).doubleValue(speedGood2.getUnits());
assertEquals(firstDifference, speed1firstValue + speed2firstValue,0);
// test that original series have dependents
assertEquals("first series has dependents", 2, speedGood1.getDependents()
.size());
assertEquals("second series has dependents", 1, speedGood2.getDependents()
.size());
// test that new series has predecessors
assertNotNull("new series has precedent", newS.getPrecedent());
}
@Test
@SuppressWarnings(
{"rawtypes", "unchecked"})
public void testSubtractionSingleton()
{
StoreGroup store = new SampleData().getData(10);
List<ICollection> selection = new ArrayList<ICollection>(3);
// test invalid dimensions
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
IQuantityCollection<Velocity> speedSingle =
new StockTypes.NonTemporal.SpeedMSec("singleton", null);
speedSingle.add(2d);
selection.add(speedGood1);
selection.add(speedSingle);
Collection<ICommand<ICollection>> commands =
new SubtractQuantityOperation().actionsFor(selection, store, context);
assertEquals("got two commands", 4, commands.size());
// have a look
ICommand<ICollection> first = commands.iterator().next();
first.execute();
ICollection output = first.getOutputs().iterator().next();
assertNotNull("produced output", output);
assertEquals("correct size", speedGood1.getValuesCount(), output
.getValuesCount());
assertEquals("correct value", 2.3767, speedGood1.getValues().get(0)
.doubleValue(Velocity.UNIT) * 2, 0.001);
}
@Test
@SuppressWarnings(
{"rawtypes", "unchecked"})
public void testAddSingleton()
{
StoreGroup store = new SampleData().getData(10);
List<ICollection> selection = new ArrayList<ICollection>(3);
// test invalid dimensions
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
IQuantityCollection<Velocity> speedSingle =
new StockTypes.NonTemporal.SpeedMSec("singleton", null);
speedSingle.add(2d);
selection.add(speedGood1);
selection.add(speedSingle);
Collection<ICommand<ICollection>> commands =
new AddQuantityOperation().actionsFor(selection, store, context);
assertEquals("got two commands", 2, commands.size());
// have a look
Iterator<ICommand<ICollection>> iter = commands.iterator();
iter.next();
ICommand<ICollection> first = iter.next();
first.execute();
IQuantityCollection<Velocity> output =
(IQuantityCollection) first.getOutputs().iterator().next();
assertNotNull("produced output", output);
assertTrue("output is temporal", output.isTemporal());
assertEquals("correct size", speedGood1.getValuesCount(), output
.getValuesCount());
assertEquals("correct value", output.getValues().get(0).doubleValue(
Velocity.UNIT), speedGood1.getValues().get(0)
.doubleValue(Velocity.UNIT) + 2, 0.001);
}
@Test
@SuppressWarnings(
{"rawtypes", "unchecked"})
public void testSubtraction()
{
StoreGroup store = new SampleData().getData(10);
int storeSize = store.size();
List<ICollection> selection = new ArrayList<ICollection>(3);
// test invalid dimensions
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
IQuantityCollection<Angle> angle1 =
(IQuantityCollection<Angle>) store.get(SampleData.ANGLE_ONE);
selection.add(speedGood1);
selection.add(angle1);
Collection<ICommand<ICollection>> commands =
new SubtractQuantityOperation().actionsFor(selection, store, context);
assertEquals("invalid collections - not same dimensions", 0, commands
.size());
selection.clear();
// test not all quantities
ICollection string1 = (ICollection) store.get(SampleData.STRING_ONE);
selection.add(speedGood1);
selection.add(string1);
commands =
new SubtractQuantityOperation().actionsFor(selection, store, context);
assertEquals("invalid collections - not all quantities", 0, commands.size());
selection.clear();
// test valid command
IQuantityCollection<Velocity> speedGood2 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_TWO);
selection.add(speedGood1);
selection.add(speedGood2);
commands =
new SubtractQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid command", 4, commands.size());
ICommand<ICollection> command = commands.iterator().next();
command.execute();
// test store has a new item in it
assertEquals("store not empty", storeSize + 1, store.size());
IQuantityCollection<Velocity> newS =
(IQuantityCollection<Velocity>) store.get(speedGood2.getName()
+ " from " + speedGood1.getName());
assertNotNull(newS);
assertEquals("correct size", 10, newS.getValuesCount());
// assert same unit
assertEquals(newS.getUnits(), speedGood1.getUnits());
double firstDifference =
newS.getValues().get(0).doubleValue(newS.getUnits());
double speed1firstValue =
speedGood1.getValues().get(0).doubleValue(speedGood1.getUnits());
double speed2firstValue =
speedGood2.getValues().get(0).doubleValue(speedGood2.getUnits());
assertEquals(firstDifference, speed1firstValue - speed2firstValue,0);
context.logError(IContext.Status.ERROR, "Error", null);
}
@SuppressWarnings("unchecked")
@Test
public void testAddLayerOperation() throws RuntimeException
{
IContext context=EasyMock.createMock(MockContext.class);
// place to store results data
StoreGroup store = new SampleData().getData(10);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
StoreGroup track1 = new StoreGroup("Track 1");
selection.add(track1);
Collection<ICommand<IStoreItem>> commands =
new AddLayerOperation().actionsFor(selection, store, context);
assertEquals("Valid number of commands", 1, commands.size());
commands.contains(track1);
Iterator<ICommand<IStoreItem>> iterator = commands.iterator();
ICommand<IStoreItem> firstItem = iterator.next();
EasyMock.expect(context.getInput("Add layer", "Provide name for new folder",
"")).andReturn("").times(2);
EasyMock.expect(context.getInput("Add layer", "Provide name for new folder",
"")).andReturn(null).times(1);
EasyMock.expect(context.getInput("Add layer", "Provide name for new folder",
"")).andReturn("").times(1);
EasyMock.replay(context);
firstItem.execute();
//Coverage purpose for Equals method.
boolean equals = firstItem.equals(track1);
assertEquals("Two objects are not equal", false,equals);
//Coverage purpose for Hash code method
long hashCode= firstItem.hashCode();
final int prime = 31;
int result = 1;
result = prime * result + firstItem.getUUID().hashCode();
assertEquals(result, hashCode);
assertEquals("Parent not defined",null, firstItem.getParent());
firstItem.setParent(track1);
assertEquals("Parent defined as a Track1",track1, firstItem.getParent());
assertNotNull("UUID is generated randomly",firstItem.getUUID());
StoreGroup dummyStoreTrack = new StoreGroup("Dummy Store Track");
firstItem.metadataChanged(dummyStoreTrack);
assertTrue("First Item is dynamic", firstItem.getDynamic());
assertEquals("Store Item Description","Add a new layer",firstItem.getDescription());
firstItem.execute();
firstItem.collectionDeleted(dummyStoreTrack);
try{
firstItem.undo();
}catch(Throwable throwable){
Assert.assertEquals(true, throwable instanceof UnsupportedOperationException);
}
try{
firstItem.redo();
}catch(Throwable throwable){
Assert.assertEquals(true, throwable instanceof UnsupportedOperationException);
}
assertEquals("CanUndo operation",false, firstItem.canRedo());
assertEquals("CanRedo operation",false, firstItem.canUndo());
boolean hasChildren = firstItem.hasChildren();
assertEquals("Parent have children",true,hasChildren);
firstItem.execute();
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
selection = new ArrayList<>();
selection.add(speedGood1);
commands = new AddLayerOperation().actionsFor(selection, store, context);
assertEquals("invalid number of inputs", 1, commands.size());
for (ICommand<IStoreItem> iCommand : commands)
{
iCommand.execute();
iCommand.dataChanged(speedGood1);
}
}
@Test
public void testCreateSingletonGenerator(){
StoreGroup store = new SampleData().getData(10);
CreateSingletonGenerator generator= new CreateSingletonGenerator("dimensionless") {
@Override
protected QuantityCollection<?> generate(String name, ICommand<?> precedent) {
return new StockTypes.NonTemporal.DimensionlessDouble(name, precedent);
}
};
assertNotNull("Create Single Generator is not NULL", generator);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
StoreGroup storeGroup = new StoreGroup("Track 1");
selection.add(storeGroup);
IContext mockContext=EasyMock.createMock(MockContext.class);
Collection<ICommand<IStoreItem>> singleGeneratorActionFor = generator.actionsFor(selection, store, mockContext);
assertEquals("Create location collection size", 1,singleGeneratorActionFor.size());
ICommand<IStoreItem> singleGenCommand = singleGeneratorActionFor.iterator().next();
EasyMock.expect(mockContext.getInput("New variable", "Enter name for variable", "")).andReturn("new dimensionless").times(1);
EasyMock.expect(mockContext.getInput("New variable", "Enter initial value for variable", "")).andReturn("1234.56").times(1);
EasyMock.replay(mockContext);
singleGenCommand.execute();
}
@Test
public void testCreateLocationAction(){
StoreGroup store = new SampleData().getData(10);
CreateLocationAction createLocationAction= new CreateLocationAction();
assertNotNull("Create Location action is not NULL", createLocationAction);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
StoreGroup storeGroup = new StoreGroup("Track 1");
selection.add(storeGroup);
IContext mockContext=EasyMock.createMock(MockContext.class);
Collection<ICommand<IStoreItem>> actionsFor = createLocationAction.actionsFor(selection, store, mockContext);
assertEquals("Create location collection size", 1,actionsFor.size());
Iterator<ICommand<IStoreItem>> creationLocIterator = actionsFor.iterator();
ICommand<IStoreItem> command= creationLocIterator.next();
EasyMock.expect(mockContext.getInput("New fixed location", "Enter name for location", "")).andReturn("seriesName").times(1);
EasyMock.expect(mockContext.getInput("New location","Enter initial value for latitude", "")).andReturn("123.23").times(1);
EasyMock.expect(mockContext.getInput("New location","Enter initial value for longitude", "")).andReturn("3456.78").times(1);
EasyMock.replay(mockContext);
command.execute();
}
@Test
public void testExportCsvToFileAction(){
StoreGroup store = new SampleData().getData(10);
ExportCsvToFileAction exportCSVFileAction=new ExportCsvToFileAction();
assertNotNull(exportCSVFileAction);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
@SuppressWarnings("unchecked")
IQuantityCollection<Velocity> speedGood1 = (IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
selection.add(speedGood1);
IContext mockContext=EasyMock.createMock(MockContext.class);
Collection<ICommand<IStoreItem>> exportActionfor = exportCSVFileAction.actionsFor(selection, store, mockContext);
assertEquals("Export CSV file collection size", 1,exportActionfor.size());
Iterator<ICommand<IStoreItem>> iterator=exportActionfor.iterator();
ICommand<IStoreItem> command = iterator.next();
EasyMock.expect(mockContext.getCsvFilename()).andReturn("ExportCSV.csv").times(1);
EasyMock.expect(mockContext.openQuestion("Overwrite '" + "ExportCSV.csv" + "'?",
"Are you sure you want to overwrite '" + "ExportCSV.csv" + "'?")).andReturn(true).times(1);
EasyMock.replay(mockContext);
command.execute();
}
@Test
public void testCopyCsvToClipboardAction(){
StoreGroup store = new SampleData().getData(10);
CopyCsvToClipboardAction copyCSVToClipAction=new CopyCsvToClipboardAction();
assertNotNull(copyCSVToClipAction);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
@SuppressWarnings("unchecked")
IQuantityCollection<Velocity> speedGood1 = (IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
selection.add(speedGood1);
IContext mockContext=EasyMock.createMock(MockContext.class);
Collection<ICommand<IStoreItem>> copyCSVActionfor = copyCSVToClipAction.actionsFor(selection, store, mockContext);
assertEquals("Copy CSV file collection size", 1,copyCSVActionfor.size());
Iterator<ICommand<IStoreItem>> copyrIterator=copyCSVActionfor.iterator();
ICommand<IStoreItem> copyCommand = copyrIterator.next();
copyCommand.execute();
}
@Test
public void testUnitaryMathOperation(){
UnitaryMathOperation clearUnit=new UnitaryMathOperation("Clear units"){
public double calcFor(double val){
return val;
}
protected Unit<?> getUnits(IQuantityCollection<?> input){
return Dimensionless.UNIT;
}
};
assertNotNull(clearUnit);
double calcFor = clearUnit.calcFor(123.45);
assertTrue("Calc for",123.45==calcFor);
}
@Test
public void testOperations(){
// place to store results data
HashMap<String, List<IOperation<?>>> ops = OperationsLibrary.getOperations();
List<IOperation<?>> create = ops.get(OperationsLibrary.CREATE);
assertEquals("Creation size",7, create.size());
//Administrator Operations.
List<IOperation<?>> adminOperations = ops.get(OperationsLibrary.ADMINISTRATION);
assertEquals("Creation size",6, adminOperations.size());
List<IOperation<?>> topLevel = OperationsLibrary.getTopLevel();
assertNotNull(topLevel);
}
@Test
@SuppressWarnings("unchecked")
public void testDivision()
{
// place to store results data
StoreGroup store = new SampleData().getData(10);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
ICollection speedGood2 = (ICollection) store.get(SampleData.SPEED_TWO);
IQuantityCollection<Length> length1 =
(IQuantityCollection<Length>) store.get(SampleData.LENGTH_ONE);
ICollection string1 = (ICollection) store.get(SampleData.STRING_ONE);
IQuantityCollection<Dimensionless> factor =
(IQuantityCollection<Dimensionless>) store
.get(SampleData.FLOATING_POINT_FACTOR);
ICollection speedGood1Bigger =
(ICollection) new SampleData().getData(20).get(SampleData.SPEED_ONE);
// /
// / TEST NOT APPLICABLE INPUT
// /
// test invalid number of inputs
selection.add(speedGood1);
selection.add(speedGood2);
selection.add(length1);
Collection<ICommand<IStoreItem>> commands =
new DivideQuantityOperation().actionsFor(selection, store, context);
assertEquals("invalid number of inputs", 0, commands.size());
// test not all quantities
selection.clear();
selection.add(speedGood1);
selection.add(string1);
commands =
new DivideQuantityOperation().actionsFor(selection, store, context);
assertEquals("not all quantities", 0, commands.size());
// test different size
selection.clear();
selection.add(speedGood1);
selection.add(speedGood1Bigger);
commands =
new DivideQuantityOperation().actionsFor(selection, store, context);
assertEquals("collection not same size", 2, commands.size());
// /
// / TEST APPLICABLE INPUT
// /
// test length over speed
selection.clear();
selection.add(length1);
selection.add(speedGood1);
commands =
new DivideQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid input", 2, commands.size());
ICommand<IStoreItem> command = commands.iterator().next();
command.execute();
IStoreItem output = command.getOutputs().iterator().next();
IQuantityCollection<Quantity> iQ = (IQuantityCollection<Quantity>) output;
assertEquals("correct units", "[T]", iQ.getUnits().getDimension()
.toString());
store.clear();
command.execute();
assertEquals(1, store.size());
IQuantityCollection<Duration> duration =
(IQuantityCollection<Duration>) store.iterator().next();
assertEquals(speedGood1.getValuesCount(), duration.getValuesCount());
double firstDuration =
duration.getValues().get(0).doubleValue(duration.getUnits());
double firstLength =
length1.getValues().get(0).doubleValue(length1.getUnits());
double firstSpeed =
speedGood1.getValues().get(0).doubleValue(speedGood1.getUnits());
assertEquals(firstLength / firstSpeed, firstDuration,0);
// test length over factor
selection.clear();
selection.add(length1);
selection.add(factor);
commands =
new DivideQuantityOperation().actionsFor(selection, store, context);
assertEquals("valid input", 2, commands.size());
Iterator<ICommand<IStoreItem>> iterator = commands.iterator();
command = iterator.next();
store.clear();
command.execute();
assertEquals(1, store.size());
IQuantityCollection<Length> resultLength =
(IQuantityCollection<Length>) store.iterator().next();
assertEquals(length1.getValuesCount(), resultLength.getValuesCount());
double firstResultLength =
resultLength.getValues().get(0).doubleValue(resultLength.getUnits());
double factorValue =
factor.getValues().get(0).doubleValue(factor.getUnits());
assertEquals(firstLength / factorValue, firstResultLength,0);
// test command #2: factor over length
command = iterator.next();
store.clear();
command.execute();
IQuantityCollection<Quantity> resultQuantity =
(IQuantityCollection<Quantity>) store.iterator().next();
// assert expected unit (1/m)
assertEquals("1/" + length1.getUnits().toString(), resultQuantity
.getUnits().toString());
assertEquals(length1.getValuesCount(), resultQuantity.getValuesCount());
double firstResultQuantity =
resultQuantity.getValues().get(0)
.doubleValue(resultQuantity.getUnits());
assertEquals(factorValue / firstLength, firstResultQuantity,0);
}
@Test
@SuppressWarnings("unchecked")
public void testGenerateDummyDataOperation()
{
StoreGroup store = new SampleData().getData(10);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
Collection<ICommand<IStoreItem>> commands =
new GenerateDummyDataOperation("Generate Dummy Data Test",1).actionsFor(selection, store, context);
assertEquals("Valid number of commands", 1, commands.size());
IQuantityCollection<Velocity> speedGood1 =
(IQuantityCollection<Velocity>) store.get(SampleData.SPEED_ONE);
selection = new ArrayList<>();
for (ICommand<IStoreItem> iCommand : commands)
{
iCommand.execute();
iCommand.dataChanged(speedGood1);
}
}
@Test
public void testDeleteCollectionOperation(){
StoreGroup store = new SampleData().getData(10);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
ICollection speedGood1 = (ICollection) store.get(SampleData.SPEED_ONE);
ICollection string1 = (ICollection) store.get(SampleData.STRING_ONE);
selection.add(speedGood1);
selection.add(string1);
DeleteCollectionOperation deleteCollectionOperation=new DeleteCollectionOperation();
Collection<ICommand<IStoreItem>> commands =
deleteCollectionOperation.actionsFor(selection, store, context);
assertEquals("Delete collection operation", 1, commands.size());
ICommand<IStoreItem> command = commands.iterator().next();
command.execute();
}
@Test
public void testBearingBetweenTracksOperation() throws IOException{
StoreGroup store = new SampleData().getData(10);
List<IStoreItem> selection = new ArrayList<IStoreItem>();
File file = TestCsvParser.getDataFile("americas_cup/usa.csv");
assertTrue(file.isFile());
File file2 = TestCsvParser.getDataFile("americas_cup/nzl.csv");
assertTrue(file2.isFile());
CsvParser parser = new CsvParser();
List<IStoreItem> items = parser.parse(file.getAbsolutePath());
assertEquals("correct group", 1, items.size());
StoreGroup group = (StoreGroup) items.get(0);
assertEquals("correct num collections", 3, group.size());
ICollection firstColl = (ICollection) group.get(2);
assertEquals("correct num rows", 1708, firstColl.getValuesCount());
List<IStoreItem> items2 = parser.parse(file2.getAbsolutePath());
assertEquals("correct group", 1, items2.size());
StoreGroup group2 = (StoreGroup) items2.get(0);
assertEquals("correct num collections", 3, group2.size());
ICollection secondColl = (ICollection) group2.get(2);
assertEquals("correct num rows", 1708, secondColl.getValuesCount());
TemporalLocation track1 = (TemporalLocation) firstColl;
TemporalLocation track2 = (TemporalLocation) secondColl;
selection.add(track1);
selection.add(track2);
Collection<ICommand<IStoreItem>> commands =
new BearingBetweenTracksOperation().actionsFor(selection, store, context);
assertEquals("Bearing Between Tracks operation", 2, commands.size());
Iterator<ICommand<IStoreItem>> iterator = commands.iterator();
ICommand<IStoreItem> command = iterator.next();
command.execute();
command = iterator.next();
command.execute();
boolean numeric = CsvParser.isNumeric("123");
assertTrue(numeric);
numeric = CsvParser.isNumeric("NAN");
assertTrue(!numeric);
}
}