@Test
public void evalTest() {

    evaluate("1", 1);
    evaluate("1f", 1f);
    evaluate("1d", 1d);
    evaluate("1f + timeSeries['foo']", 4);
    evaluate("1 + timeSeries['foo']", 4);
    evaluate("1.1 + timeSeries['foo']", 4.1);
    evaluate("1d + timeSeries['foo']", 4);
    evaluate("timeSeries['foo'] + 1f", 4);
    evaluate("timeSeries['foo'] + 1", 4);
    evaluate("timeSeries['foo'] + 1.1", 4.1);
    evaluate("timeSeries['foo'] + 1d", 4);
    evaluate("timeSeries['foo'] + timeSeries['bar']", 5f);
    evaluate("1f - timeSeries['foo']", -2);
    evaluate("1 - timeSeries['foo']", -2);
    evaluate("1.1 - timeSeries['foo']", -1.9);
    evaluate("1d - timeSeries['foo']", -2);
    evaluate("timeSeries['foo'] - 1f", 2);
    evaluate("timeSeries['foo'] - 1", 2);
    evaluate("timeSeries['foo'] - 1.1", 1.9);
    evaluate("timeSeries['foo'] - 1d", 2);
    evaluate("timeSeries['foo'] - timeSeries['bar']", 1);
    evaluate("1f * timeSeries['foo']", 3);
    evaluate("1 * timeSeries['foo']", 3);
    evaluate("1d * timeSeries['foo']", 3);
    evaluate("1.1 * timeSeries['foo']", 3.3000000000000003);
    evaluate("timeSeries['foo'] * 1f", 3);
    evaluate("timeSeries['foo'] * 1", 3);
    evaluate("timeSeries['foo'] * 1.1", 3.3000000000000003);
    evaluate("timeSeries['foo'] * 1d", 3);
    evaluate("timeSeries['foo'] * timeSeries['bar']", 6);
    evaluate("timeSeries['foo'] / 2f", 1.5);
    evaluate("timeSeries['foo'] / 2", 1.5);
    evaluate("timeSeries['foo'] / 2.1", 1.4285714285714286);
    evaluate("timeSeries['foo'] / 2d", 1.5);
    evaluate("2f / timeSeries['foo']", 0.6666666666666666);
    evaluate("2 / timeSeries['foo']", 0.6666666666666666);
    evaluate("2.1 / timeSeries['foo']", 0.7000000000000001);
    evaluate("2d / timeSeries['foo']", 0.6666666666666666);
    evaluate("timeSeries['foo'] / timeSeries['bar']", 1.5);
    evaluate("(-1f).abs()", 1f);
    evaluate("timeSeries['baz'].abs()", 1f);
    evaluate("-(-2f)", 2f);
    evaluate("+(-2f)", -2f);
    evaluate("timeSeries['foo'].min(1)", 1);
    evaluate("timeSeries['foo'].min(5)", 3);
    evaluate("timeSeries['foo'].max(1)", 3);
    evaluate("timeSeries['foo'].max(5)", 5);
    evaluate("1 < timeSeries['foo']", 1);
    evaluate("1f < timeSeries['foo']", 1);
    evaluate("1.0 < timeSeries['foo']", 1);
    evaluate("timeSeries['foo'] > 1", 1);
    evaluate("timeSeries['foo'] > 1f", 1);
    evaluate("timeSeries['foo'] > 1.0", 1);
    evaluate("timeSeries['foo'] >= 1", 1);
    evaluate("timeSeries['foo'] >= 1f", 1);
    evaluate("timeSeries['foo'] >= 1.0", 1);
    evaluate("timeSeries['foo'] != 3", 0);
    evaluate("timeSeries['foo'] != 3f", 0);
    evaluate("timeSeries['foo'] != 3.0", 0);
    evaluate("timeSeries['foo'] == 3", 1);
    evaluate("timeSeries['foo'] == 3f", 1);
    evaluate("timeSeries['foo'] == 3.0", 1);
    evaluate("timeSeries['foo'] < 3", 0);
    evaluate("timeSeries['foo'] < 3f", 0);
    evaluate("timeSeries['foo'] < 3.0", 0);
    evaluate("timeSeries['foo'] <= 3", 1);
    evaluate("timeSeries['foo'] <= 3f", 1);
    evaluate("timeSeries['foo'] <= 3.0", 1);
    evaluate("timeSeries['foo'] < timeSeries['bar']", 0);
    evaluate("timeSeries['foo'] >= timeSeries['bar']", 1);
    evaluate("timeSeries['foo'].time()", ZonedDateTime.parse("2015-01-01T00:00:00Z").toInstant().toEpochMilli());
    evaluate("timeSeries['foo'].time() == time('2015-01-01T00:00:00Z')", 1);
    evaluate("timeSeries['foo'].time() <= time('2015-01-01T00:15:00Z')", 1);
    evaluate("timeSeries['foo'].time() < time('2014-01-01T00:00:00Z')", 0);
    evaluate("timeSeries['foo'] = 1", 1);
    evaluate("timeSeries['foo'] = 1.5d", 1.5d);
    evaluate("timeSeries['foo'] = 1.5", 1.5d);
}