예제 #1
0
        public void Units()
        {
            CalculationEngine engine = new CalculationEngine();

            var p = new UnitModel
            {
                This = TestPerson.CreateTestPerson()
            };

            engine.DataContext = p;

            var expression = engine.Parse("This.Age*Y*5.0000");

            Console.WriteLine(expression.Evaluate());
        }
예제 #2
0
 public static TestPerson CreateTestPerson()
 {
     var p = new TestPerson();
     p.Name = "Test Person";
     p.Birth = DateTime.Today.AddYears(-30);
     p.Male = true;
     for (int i = 0; i < 5; i++)
     {
         var c = new TestPerson();
         c.Name = "Test Child " + i.ToString();
         c.Birth = DateTime.Today.AddYears(-i);
         c.Male = i % 2 == 0;
         p.Children.Add(c);
         p.ChildrenDct.Add(c.Name, c);
     }
     return p;
 }
예제 #3
0
        public static TestPerson CreateTestPerson()
        {
            var p = new TestPerson();

            p.Name  = "Test Person";
            p.Code  = "Code";
            p.Id    = Guid.Parse("96C5888C-6C75-43DD-A372-2A3398DAE038");
            p.Birth = DateTime.Today.AddYears(-30);
            p.Male  = true;
            for (int i = 0; i < 5; i++)
            {
                var c = new TestPerson();
                c.Name  = "Test Child " + i.ToString();
                c.Id    = Guid.Parse(i + "6C5888C-6C75-43DD-A372-2A3398DAE038");
                c.Birth = DateTime.Today.AddYears(-i);
                c.Male  = i % 2 == 0;
                p.Children.Add(c);
            }
            return(p);
        }
예제 #4
0
        public void Parse()
        {
            CalculationEngine engine = new CalculationEngine();

            // test DataContext
            var dc = engine.DataContext;
            var p  = TestPerson.CreateTestPerson();

            engine.DataContext = p;

            var expression  = engine.Parse("Parent.Children(2).Address");
            var expression1 = engine.Parse("Parent.ChildrenDct('Test Child 58').Address");

            //expression.Validate();
            //expression1.Validate();

            p.Parent         = TestPerson.CreateTestPerson();
            p.Parent.Address = new Address()
            {
                Street = "sdf"
            };
            expression1.Evaluate();
        }
예제 #5
0
        public void Test()
        {
            CalculationEngine engine = new CalculationEngine();

            // adjust culture
            var cultureInfo = engine.CultureInfo;

            engine.CultureInfo = System.Globalization.CultureInfo.InvariantCulture;

            // test internal operators
            engine.Test("0", 0.0);
            engine.Test("+1", 1.0);
            engine.Test("-1", -1.0);
            engine.Test("1+1", 1 + 1.0);
            engine.Test("1*2*3*4*5*6*7*8*9", 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9.0);
            engine.Test("1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1))))))))))", 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1 / (1 + 1.0)))))))))));
            engine.Test("((1+2)*(2+3)/(4+5))^0.123", Math.Pow((1 + 2) * (2 + 3) / (4 + 5.0), 0.123));
            engine.Test("10%", 0.1);
            engine.Test("1e+3", 1000.0);

            // test simple variables
            engine.Variables.Add("one", 1);
            engine.Variables.Add("x", 1);
            engine.Variables.Add("x2", "1");
            engine.Variables.Add("two", 2);
            engine.Test("one + two", 3);
            engine.Test("x2='1'", true);

            engine.Test("2*x+1", 3);
            engine.Test("(two + two)^2", 16);
            engine.Variables.Clear();

            // test DataContext
            var dc = engine.DataContext;
            var p  = TestPerson.CreateTestPerson();

            p.Parent           = TestPerson.CreateTestPerson();
            engine.DataContext = p;
            engine.Test("Name", "Test Person");
            engine.Functions.Remove("CODE");
            Assert.IsTrue(engine.Validate <bool>("Code='Code'"));
            engine.Test("Parent.Name", "Test Person");
            engine.Test("Name.Length * 2", p.Name.Length * 2);
            engine.Test("Children.Count", p.Children.Count);
            engine.Test("Children(2).Name", p.Children[2].Name);
            engine.Test("ChildrenDct(\"Test Child 2\").Name", p.ChildrenDct["Test Child 2"].Name);
            engine.Test("ChildrenDct('Test Child 2').Name", p.ChildrenDct["Test Child 2"].Name);
            engine.Test("ChildrenIdDct('16C5888C-6C75-43DD-A372-2A3398DAE038').Name", p.ChildrenDct["Test Child 1"].Name);
            engine.Test("ChildrenDct.Count", p.ChildrenDct.Count);
            engine.DataContext = dc;

            // test functions


            // COMPARE TESTS
            engine.Test("5=5", true);
            engine.Test("'2'='2'", true);
            engine.Test("5==5", true);
            engine.Test("6==5", false);
            engine.Test("6=5", false);
            engine.Test("6<5", false);
            engine.Test("6>5", true);
            engine.Test("5<=10", true);
            engine.Test("5>=3", true);

            // LOGICAL FUNCTION TESTS

            engine.Test("5<=6.0 && 6>=3", true);
            engine.Test("true  && true", true);
            engine.Test("true  && false", false);
            engine.Test("false && true", false);
            engine.Test("false && false", false);
            engine.Test("true  || true", true);
            engine.Test("true  || false", true);
            engine.Test("false || true", true);
            engine.Test("false || false", false);

            engine.Test("AND(true, true)", true);
            engine.Test("AND(true, false)", false);
            engine.Test("AND(false, true)", false);
            engine.Test("AND(false, false)", false);
            engine.Test("OR(true, true)", true);
            engine.Test("OR(true, false)", true);
            engine.Test("OR(false, true)", true);
            engine.Test("OR(false, false)", false);
            engine.Test("NOT(false)", true);
            engine.Test("NOT(true)", false);
            engine.Test("IF(5 > 4, true, false)", true);
            engine.Test("IF(5 > 14, true, false)", false);
            engine.Test("TRUE()", true);
            engine.Test("FALSE()", false);

            // MATH/TRIG FUNCTION TESTS
            engine.Test("ABS(-12)", 12.0);
            engine.Test("ABS(+12)", 12.0);
            engine.Test("ACOS(.23)", Math.Acos(.23));
            engine.Test("ASIN(.23)", Math.Asin(.23));
            engine.Test("ATAN(.23)", Math.Atan(.23));
            engine.Test("ATAN2(1,2)", Math.Atan2(1, 2));
            engine.Test("CEILING(1.8)", Math.Ceiling(1.8));
            engine.Test("COS(1.23)", Math.Cos(1.23));
            engine.Test("COSH(1.23)", Math.Cosh(1.23));
            engine.Test("EXP(1)", Math.Exp(1));
            engine.Test("FLOOR(1.8)", Math.Floor(1.8));
            engine.Test("INT(1.8)", 1);
            engine.Test("LOG(1.8)", Math.Log(1.8, 10));   // default base is 10
            engine.Test("LOG(1.8, 4)", Math.Log(1.8, 4)); // custom base
            engine.Test("LN(1.8)", Math.Log(1.8));        // real log
            engine.Test("LOG10(1.8)", Math.Log10(1.8));   // same as Log(1.8)
            engine.Test("PI()", Math.PI);
            engine.Test("POWER(2,4)", Math.Pow(2, 4));
            //engine.Test("RAND") <= 1.0);
            //engine.Test("RANDBETWEEN(4,5)") <= 5);
            engine.Test("SIGN(-5)", -1);
            engine.Test("SIGN(+5)", +1);
            engine.Test("SIGN(0)", 0);
            engine.Test("SIN(1.23)", Math.Sin(1.23));
            engine.Test("SINH(1.23)", Math.Sinh(1.23));
            engine.Test("SQRT(144)", Math.Sqrt(144));
            engine.Test("SUM(1, 2, 3, 4)", 1 + 2 + 3 + 4.0);
            engine.Test("TAN(1.23)", Math.Tan(1.23));
            engine.Test("TANH(1.23)", Math.Tanh(1.23));
            engine.Test("TRUNC(1.23)", 1.0);
            engine.Test("PI()", Math.PI);
            engine.Test("PI", Math.PI);
            engine.Test("LN(10)", Math.Log(10));
            engine.Test("LOG(10)", Math.Log10(10));
            engine.Test("EXP(10)", Math.Exp(10));
            engine.Test("SIN(PI()/4)", Math.Sin(Math.PI / 4));
            engine.Test("ASIN(PI()/4)", Math.Asin(Math.PI / 4));
            engine.Test("SINH(PI()/4)", Math.Sinh(Math.PI / 4));
            engine.Test("COS(PI()/4)", Math.Cos(Math.PI / 4));
            engine.Test("ACOS(PI()/4)", Math.Acos(Math.PI / 4));
            engine.Test("COSH(PI()/4)", Math.Cosh(Math.PI / 4));
            engine.Test("TAN(PI()/4)", Math.Tan(Math.PI / 4));
            engine.Test("ATAN(PI()/4)", Math.Atan(Math.PI / 4));
            engine.Test("ATAN2(1,2)", Math.Atan2(1, 2));
            engine.Test("TANH(PI()/4)", Math.Tanh(Math.PI / 4));


            // TEXT FUNCTION TESTS
            engine.Test("CHAR(65)", "A");
            //engine.Test("CODE(\"A\")", 65);
            engine.Test("CONCATENATE(\"a\", \"b\")", "ab");
            engine.Test("CONCATENATE('a', 'b')", "ab");
            engine.Test("FIND(\"bra\", \"abracadabra\")", 2);
            engine.Test("FIND(\"BRA\", \"abracadabra\")", -1);
            engine.Test("LEFT(\"abracadabra\", 3)", "abr");
            engine.Test("LEFT(\"abracadabra\")", "a");
            engine.Test("LEN(\"abracadabra\")", 11);
            engine.Test("LOWER(\"ABRACADABRA\")", "abracadabra");
            engine.Test("MID(\"abracadabra\", 1, 3)", "abr");
            engine.Test("PROPER(\"abracadabra\")", "Abracadabra");
            engine.Test("REPLACE(\"abracadabra\", 1, 3, \"XYZ\")", "XYZacadabra");
            engine.Test("REPT(\"abr\", 3)", "abrabrabr");
            engine.Test("RIGHT(\"abracadabra\", 3)", "bra");
            engine.Test("SEARCH(\"bra\", \"abracadabra\")", 2);
            engine.Test("SEARCH(\"BRA\", \"abracadabra\")", 2);
            engine.Test("SUBSTITUTE(\"abracadabra\", \"a\", \"b\")", "bbrbcbdbbrb");
            engine.Test("T(123)", "123");
            engine.Test("TEXT(1234, \"n2\")", "1,234.00");
            engine.Test("TRIM(\"   hello   \")", "hello");
            engine.Test("UPPER(\"abracadabra\")", "ABRACADABRA");
            engine.Test("VALUE(\"1234\")", 1234.0);

            engine.Test("SUBSTITUTE(\"abcabcabc\", \"a\", \"b\")", "bbcbbcbbc");
            engine.Test("SUBSTITUTE(\"abcabcabc\", \"a\", \"b\", 1)", "bbcabcabc");
            engine.Test("SUBSTITUTE(\"abcabcabc\", \"a\", \"b\", 2)", "abcbbcabc");
            engine.Test("SUBSTITUTE(\"abcabcabc\", \"A\", \"b\", 2)", "abcabcabc"); // case-sensitive!

            // test taken from http://www.codeproject.com/KB/vb/FormulaEngine.aspx
            var a1  = "\"http://j-walk.com/ss/books\"";
            var exp = "RIGHT(A1,LEN(A1)-FIND(CHAR(1),SUBSTITUTE(A1,\"/\",CHAR(1),LEN(A1)-LEN(SUBSTITUTE(A1,\"/\",\"\")))))";

            engine.Test(exp.Replace("A1", a1), "books");



            // STATISTICAL FUNCTION TESTS
            engine.Test("Average(1, 3, 3, 1, true, false, \"hello\")", 2.0);
            engine.Test("AverageA(1, 3, 3, 1, true, false, \"hello\")", (1 + 3 + 3 + 1 + 1 + 0 + 0) / 7.0);
            engine.Test("Count(1, 3, 3, 1, true, false, \"hello\")", 4.0);
            engine.Test("CountA(1, 3, 3, 1, true, false, \"hello\")", 7.0);

            // restore culture
            engine.CultureInfo = cultureInfo;
        }