public void CanEvaluatePrimitives() { var env = new StandardEnvironment(); env.DefineValue("foo", "foo"); env.DefineValue("_foo_bar", "_foo_bar"); // Symbols Assert.AreEqual("foo", Evaluate("foo", env)); Assert.AreEqual("foo", Evaluate(" foo ", env)); Assert.AreEqual("_foo_bar", Evaluate("_foo_bar", env)); // Strings Assert.AreEqual("foo'bar", Evaluate("'foo''bar'", env)); Assert.AreEqual("foo\"bar\"\n\'/\\", Evaluate(@"""foo\""bar\""\n\'\/\\""", env)); // Numbers Assert.AreEqual(123, Evaluate("123")); Assert.AreEqual(1.23, Evaluate("1.23")); Assert.AreEqual(2.7e-5, Evaluate("2.7e-5")); // null and Booleans Assert.AreEqual(null, Evaluate("null")); Assert.AreEqual(false, Evaluate("false")); Assert.AreEqual(true, Evaluate("true")); // Excessive parens... Assert.AreEqual(42, Evaluate("(((23+19)))")); }
public void CanEvaluateConditionalOperator() { Assert.AreEqual("T", Evaluate("true ? 'T' : 'F'")); Assert.AreEqual("F", Evaluate("false ? 'T' : 'F'")); Assert.AreEqual(null, Evaluate("null ? 'T' : 'F'")); var env = new StandardEnvironment(); env.DefineValue("xyzzy", "Magic"); env.DefineValue("d", 5); Assert.AreEqual(5, Evaluate("xyzzy ? length(xyzzy) : -1", env)); Assert.AreEqual("Fri", Evaluate("d=0 ? 'Sun' : d=1 ? 'Mon' : d=2 ? 'Tue' : d=3 ? 'Wed' : d=4 ? 'Thu' : d=5 ? 'Fri' : d=6 ? 'Sat' : null", env)); }
public void CanEvaluateUnaryOps() { Assert.AreEqual(5, Evaluate("+5")); Assert.AreEqual(-5, Evaluate("+-5")); Assert.AreEqual(25, Evaluate("+ + +25")); Assert.AreEqual(-0.2, Evaluate(" - 0.2 ")); Assert.AreEqual(-0.2, Evaluate("- - -0.2")); Assert.AreEqual(-1.2e-03, Evaluate("-1.2e-03")); Assert.AreEqual(false, Evaluate("not true")); Assert.AreEqual(true, Evaluate("not not true")); Assert.AreEqual(true, Evaluate("not not 5")); var env = new StandardEnvironment(); env.DefineValue("foo", 42.0); Assert.AreEqual(42.0, Evaluate("foo", env)); Assert.AreEqual(false, Evaluate("not foo", env)); Assert.AreEqual(true, Evaluate("not not foo", env)); Assert.AreEqual(false, Evaluate("not not not foo", env)); Assert.AreEqual(5, Evaluate("+ +5")); Catch(() => Evaluate("++5")); Assert.AreEqual(25, Evaluate("- - 25")); Catch(() => Evaluate("-- 25")); // -- is one token }
public void CanLookupPrecedence() { // Lookup precedence for unqualified names: // defined value < standard function < field value // Qualified names are always looked up on a row of fields // defined with the qualifier. CONCAT is a standard function. var env = new StandardEnvironment(); var row = new ConstantValueTestRow("row", "CONCAT", "FOO"); const string qualifier = "qualifier"; Assert.Catch <EvaluationException>(() => env.Lookup("FOO", null)); Assert.IsInstanceOf <Function>(env.Lookup("CONCAT", null)); Assert.Catch <EvaluationException>(() => env.Lookup("CONCAT", qualifier)); env.DefineFields(row, qualifier); Assert.AreEqual("row", env.Lookup("FOO", null)); Assert.IsInstanceOf <Function>(env.Lookup("CONCAT", null)); Assert.AreEqual("row", env.Lookup("CONCAT", qualifier)); env.DefineValue("FOO", "foo"); env.DefineValue("CONCAT", "value"); Assert.AreEqual("foo", env.Lookup("FOO", null)); Assert.AreEqual("value", env.Lookup("CONCAT", null)); Assert.AreEqual("row", env.Lookup("CONCAT", qualifier)); env.ForgetValue("CONCAT"); env.ForgetValue("FOO"); Assert.AreEqual("row", env.Lookup("FOO", null)); Assert.IsInstanceOf <Function>(env.Lookup("CONCAT", null)); Assert.AreEqual("row", env.Lookup("CONCAT", qualifier)); env.ForgetFields("qualifier"); Assert.Catch <EvaluationException>(() => env.Lookup("FOO", null)); Assert.IsInstanceOf <Function>(env.Lookup("CONCAT", null)); Assert.Catch <EvaluationException>(() => env.Lookup("CONCAT", qualifier)); }
public void CanLookupIgnoreCase() { var envIgnoreCase = new StandardEnvironment(); envIgnoreCase.DefineValue("foo", "bar"); Assert.AreEqual("bar", envIgnoreCase.Lookup("foo", null)); Assert.AreEqual("bar", envIgnoreCase.Lookup("FOO", null)); var ex1 = Assert.Catch <EvaluationException>(() => envIgnoreCase.Lookup("foo", "qualifier")); Console.WriteLine(@"Expected exception: {0}", ex1.Message); Assert.IsInstanceOf(typeof(Function), envIgnoreCase.Lookup("TRIM", null)); Assert.IsInstanceOf(typeof(Function), envIgnoreCase.Lookup("Trim", null)); }
public void CanEvaluateNullCoalescingOperator() { Assert.AreEqual("foo", Evaluate("'foo' ?? 'bar'")); Assert.AreEqual("bar", Evaluate("null ?? 'bar'")); // Here's how ?? is different from || (logical or): Assert.AreEqual(false, Evaluate("false ?? 'bar'")); Assert.AreEqual(true, Evaluate("false or 'bar'")); // "bar" // ?? binds tighter than ?: var env = new StandardEnvironment(); env.DefineValue("nothing", null); Assert.AreEqual("alt", Evaluate("nothing ?? false ? null ?? 'consequent' : 'alt' ?? 'alternative'", env)); }
public void CanLookupQualified() { var env = new StandardEnvironment(false); env.DefineValue("foo", "bar"); Assert.AreEqual("bar", env.Lookup("foo", null)); var ex1 = Assert.Catch <EvaluationException>(() => env.Lookup("foo", "qualifier")); Console.WriteLine(@"Expected exception: {0}", ex1.Message); Assert.IsInstanceOf <Function>(env.Lookup("TRIM", null)); var ex2 = Assert.Catch <EvaluationException>(() => env.Lookup("TRIM", "qualifier")); Console.WriteLine(@"Expected exception: {0}", ex2.Message); }
public void CanEvaluateArithmetic() { Assert.AreEqual(-7, Evaluate(" 1 - 3 - 5 ")); Assert.AreEqual(3, Evaluate("1-(3-5)")); Assert.AreEqual(2, Evaluate("1-2+3")); Assert.AreEqual(-6.28, Evaluate("3.14*-2")); // *- is two tokens! Assert.AreEqual(0, Evaluate("12-3*4")); Assert.AreEqual(36, Evaluate("(12-3)*4")); var env = new StandardEnvironment(); env.DefineValue("LB", 0.46); Assert.IsTrue(Math.Abs((double)Evaluate("LB/2", env)) - 0.23 < double.Epsilon); Assert.IsTrue(Math.Abs((double)Evaluate("0.5*LB", env)) - 0.23 < double.Epsilon); }
public void CanCaseInSensitive() { const string name = "fAlSe"; // When ignoring case, "fAlSe" will be recognized as the built-in value false: var envIgnoreCase = new StandardEnvironment(); envIgnoreCase.DefineValue(name, "TheEnv"); Assert.AreEqual(false, Dump(ExpressionEvaluator.Create("fAlSe")).Evaluate(envIgnoreCase)); // When respecting case, "fAlSe" is just a name to be looked up in the environment: var envRespectCase = new StandardEnvironment(false); envRespectCase.DefineValue(name, "TheEnv"); Assert.AreEqual("TheEnv", Dump(ExpressionEvaluator.Create("fAlSe", false)).Evaluate(envRespectCase)); }