package nodebox.function; import com.google.common.collect.ImmutableList; import nodebox.node.*; import nodebox.util.Assertions; import org.junit.Test; import java.util.List; import static nodebox.function.MathFunctions.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class MathFunctionsTest { private final FunctionLibrary mathLibrary = MathFunctions.LIBRARY; private final FunctionRepository functions = FunctionRepository.of(mathLibrary); private final NodeLibrary testLibrary = NodeLibrary.create("test", Node.ROOT, functions); private List<?> renderNode(Node node) { return new NodeContext(testLibrary.withRoot(node)).renderNode("/"); } @Test public void testInvertExists() { assertTrue(functions.hasFunction("math/negate")); assertTrue(mathLibrary.hasFunction("negate")); Function function = functions.getFunction("math/negate"); assertEquals("negate", function.getName()); } @Test(expected = NodeRenderException.class) public void testCallInvertWithNoArguments() { Node invertNode = Node.ROOT.withFunction("math/negate"); renderNode(invertNode); } @Test public void testCallInvert() { Node invertNode = Node.ROOT .withFunction("math/negate") .withInputAdded(Port.floatPort("value", 5)); assertEquals(ImmutableList.of(-5.0), renderNode(invertNode)); } /** * Test if the insertion order of the ports is respected. * <p/> * This method tests a non-commutative operation in two directions to see if both work. */ @Test public void testPortOrder() { Node subtract1 = Node.ROOT .withFunction("math/subtract") .withInputAdded(Port.floatPort("a", 10)) .withInputAdded(Port.floatPort("b", 3)); assertEquals(ImmutableList.of(7.0), renderNode(subtract1)); Node subtract2 = Node.ROOT .withName("subtract2") .withFunction("math/subtract") .withInputAdded(Port.floatPort("b", 3)) .withInputAdded(Port.floatPort("a", 10)); assertEquals(ImmutableList.of(-7.0), renderNode(subtract2)); } @Test public void testAbs() { assertEquals(0.0, MathFunctions.abs(0.0), 0.0); assertEquals(42.0, MathFunctions.abs(42.0), 0.0); assertEquals(42.0, MathFunctions.abs(-42.0), 0.0); } @Test public void testMod() { assertEquals(0.0, MathFunctions.mod(10, 2), 0.0); assertEquals(3.0, MathFunctions.mod(10, 7), 0.0); } @Test(expected = IllegalArgumentException.class) public void testModByZero() { MathFunctions.mod(10, 0); } @Test public void testSum() { assertEquals(0.0, MathFunctions.sum(null), 0.001); assertEquals(0.0, MathFunctions.sum(ImmutableList.<Double>of()), 0.001); assertEquals(6.0, MathFunctions.sum(ImmutableList.of(1.0, 2.0, 3.0)), 0.001); assertEquals(-6.0, MathFunctions.sum(ImmutableList.of(-1.0, -2.0, -3.0)), 0.001); } @Test public void testMax() { assertEquals(0.0, MathFunctions.max(ImmutableList.<Double>of()), 0.001); assertEquals(3.0, MathFunctions.max(ImmutableList.of(1.0, 2.0, 3.0)), 0.001); assertEquals(-1.0, MathFunctions.max(ImmutableList.of(-1.0, -2.0, -3.0)), 0.001); } @Test public void testMin() { assertEquals(0.0, MathFunctions.min(ImmutableList.<Double>of()), 0.001); assertEquals(1.0, MathFunctions.min(ImmutableList.of(1.0, 2.0, 3.0)), 0.001); assertEquals(-3.0, MathFunctions.min(ImmutableList.of(-1.0, -2.0, -3.0)), 0.001); } @Test public void testRandomNumbers() { List<Double> numbers = MathFunctions.randomNumbers(3, -10.0, 10.0, 42); assertEquals(3.89263, numbers.get(0), 0.001); assertEquals(4.95359, numbers.get(1), 0.001); assertEquals(4.66839, numbers.get(2), 0.001); } @Test public void testSample() { Assertions.assertResultsEqual(sample(0, 1, 2)); Assertions.assertResultsEqual(sample(1, 100, 200), 150.0); Assertions.assertResultsEqual(sample(2, 100, 200), 100.0, 200.0); Assertions.assertResultsEqual(sample(3, 100, 200), 100.0, 150.0, 200.0); Assertions.assertResultsEqual(sample(4, 100, 250), 100.0, 150.0, 200.0, 250.0); Assertions.assertResultsEqual(sample(3, 200, 100), 200.0, 150.0, 100.0); Assertions.assertResultsEqual(sample(3, 1, 1), 1.0, 1.0, 1.0); List<Double> values = sample(1000, 0, 100); double lastValue = values.get(values.size() - 1); assertEquals("The last value needs to be exactly 100.", 100.0, lastValue, 0.0); assertTrue("The last value needs to be exactly 100.", lastValue <= 100.0); } @Test public void testConvertRange() { assertEquals(0.5, convertRange(50, 0, 100, 0, 1, OVERFLOW_IGNORE), 0.001); assertEquals(0.25, convertRange(75, 0, 100, 1, 0, OVERFLOW_IGNORE), 0.001); } @Test public void testRound() { assertEquals(5L, round(5.0)); assertEquals(5L, round(5.4)); assertEquals(6L, round(5.5)); assertEquals(6L, round(5.9)); } }