Beispiel #1
0
        public void TimeSpanDateTime()
        {
            var simple = FSBuilder.Take <TimeSpanObject>("|", typeof(TimeSpanObject).GetProperty("A")).TakeRest(typeof(TimeSpanObject).GetField("B")).Seal();

            var span1 = System.TimeSpan.FromDays(1);
            var span2 = System.TimeSpan.FromMilliseconds((new Random()).Next(1000000));

            var obj = new TimeSpanObject();

            simple(span1 + "|" + span2, obj);

            Assert.AreEqual(span1, obj.A);
            Assert.AreEqual(span2, obj.B.Value);

            var complex = FSBuilder.Take <TimeSpanObject>("|", typeof(TimeSpanObject).GetProperty("A"), format: "G").TakeRest(typeof(TimeSpanObject).GetField("B"), format: "g").Seal();

            complex(span2.ToString("G") + "|" + span1.ToString("g"), obj);

            Assert.AreEqual(span2, obj.A);
            Assert.AreEqual(span1, obj.B.Value);

            var date = FSBuilder.Take <TimeSpanObject>("|", "C").Seal();

            var newDate = DateTime.UtcNow;

            date(newDate + "|", obj);
            Assert.AreEqual(newDate.ToString(), obj.C.ToString());
        }
Beispiel #2
0
        public void NumberAsEnum()
        {
            var simple = FSBuilder.Take <EnumObject>("|", "A").Else((s, o) => { throw new InvalidOperationException(); }).Seal();

            var obj = new EnumObject();

            simple("2|", obj);

            Assert.AreEqual(EnumObject.Blah.Bar, obj.A);
        }
Beispiel #3
0
        public void StandAloneTakeN()
        {
            var parser = FSBuilder.Take <DecimalObject>(4, typeof(DecimalObject).GetProperty("A")).Seal();

            var obj = new DecimalObject();

            parser("12345678", obj);

            Assert.AreEqual(1234m, obj.A);
        }
Beispiel #4
0
        public void Overflows()
        {
            var parse =
                FSBuilder
                .Take <ValueObject>(",", "A")
                .Take(",", "B")
                .Take(",", "C")
                .TakeRest("D")
                .Else((s, o) => { throw new Exception(); })
                .Seal();

            var obj = new ValueObject();

            parse("1,2,3,4", obj);
            Assert.AreEqual(1, obj.A);
            Assert.AreEqual(2, obj.B);
            Assert.AreEqual(3, obj.C);
            Assert.AreEqual(4, obj.D);

            try
            {
                parse(byte.MaxValue + ",1,2,3", obj);
                Assert.Fail("byte should be exceeded");
            }
            catch (Exception) { }

            try
            {
                parse("1," + ushort.MaxValue + ",2,3", obj);
                Assert.Fail("short should be exceeded");
            }
            catch (Exception) { }

            try
            {
                parse("1,2," + uint.MaxValue + ",3", obj);
                Assert.Fail("int should be exceeded");
            }
            catch (Exception) { }

            try
            {
                parse("1,2,3," + ulong.MaxValue, obj);
                Assert.Fail("long should be exceeded");
            }
            catch (Exception) { }

            parse(sbyte.MaxValue + "," + short.MaxValue + "," + int.MaxValue + "," + long.MaxValue, obj);
            Assert.AreEqual(sbyte.MaxValue, obj.A);
            Assert.AreEqual(short.MaxValue, obj.B);
            Assert.AreEqual(int.MaxValue, obj.C);
            Assert.AreEqual(long.MaxValue, obj.D);
        }
Beispiel #5
0
        public void FloatsDoubles()
        {
            var parse = FSBuilder.Take <FloatAndDouble>(",", "A").TakeRest("B").Seal();

            var rand = new Random();
            var a    = (float)rand.NextDouble();
            var b    = rand.NextDouble();

            var obj = new FloatAndDouble();

            parse(a + "," + b, obj);

            Assert.AreEqual(a.ToString(), obj.A.ToString());
            Assert.AreEqual(b.ToString(), obj.B.ToString());
        }
Beispiel #6
0
        public void Decimals()
        {
            var parser =
                FSBuilder
                .Take <DecimalObject>(",", typeof(DecimalObject).GetProperty("A"))
                .TakeRest(typeof(DecimalObject).GetProperty("B"))
                .Seal();

            var obj = new DecimalObject();

            parser("123.45,8675309", obj);

            Assert.AreEqual(123.45m, obj.A);
            Assert.AreEqual(8675309m, obj.B);
        }
Beispiel #7
0
        public void Bools()
        {
            var parser =
                FSBuilder
                .Take <BoolObject>(",", "A")
                .Take(",", "B")
                .TakeRest("C")
                .Seal();

            var obj = new BoolObject();

            parser("True,1,false", obj);
            Assert.IsTrue(obj.A);
            Assert.IsTrue(obj.B);
            Assert.IsFalse(obj.C.Value);
        }
Beispiel #8
0
        public void NullableSkip()
        {
            var parser =
                FSBuilder
                .Take <BoolObject>(",", "A")
                .Take(",", "C")
                .TakeRest("B")
                .Seal();

            var obj = new BoolObject();

            parser("True,,false", obj);

            Assert.IsTrue(obj.A);
            Assert.IsFalse(obj.B);
            Assert.IsNull(obj.C);
        }
Beispiel #9
0
        public void FixedSteps()
        {
            var parse =
                FSBuilder
                .Take <UnsignedObject>(4, "A")
                .Back(2)
                .Take(",", "B")
                .Skip(2)
                .TakeRest("C")
                .Seal();

            var obj = new UnsignedObject();

            parse("1234,5678", obj);
            Assert.AreEqual((ulong)1234, obj.A);
            Assert.AreEqual((uint)34, obj.B);
            Assert.AreEqual((ushort)78, obj.C);
        }
Beispiel #10
0
        public void Unsigned()
        {
            var parse =
                FSBuilder
                .Take <UnsignedObject>(",", "A")
                .Take(",", "B")
                .Take(",", "C")
                .TakeRest("D")
                .Seal();

            var obj = new UnsignedObject();

            parse(ulong.MaxValue + "," + uint.MaxValue + "," + ushort.MaxValue + "," + byte.MaxValue, obj);

            Assert.AreEqual(ulong.MaxValue, obj.A);
            Assert.AreEqual(uint.MaxValue, obj.B);
            Assert.AreEqual(ushort.MaxValue, obj.C);
            Assert.AreEqual(byte.MaxValue, obj.D);
        }
Beispiel #11
0
        public void Guids()
        {
            var parser =
                FSBuilder
                .Take <GuidObj>(",", "A")
                .TakeRest("B", "X")
                .Else((s, o) => { throw new Exception(); })
                .Seal();

            var a = Guid.NewGuid();
            var b = Guid.NewGuid();

            var obj = new GuidObj();

            parser(a + "," + b.ToString("X"), obj);

            Assert.AreEqual(obj.A, a);
            Assert.AreEqual(obj.B.Value, b);
        }
Beispiel #12
0
        public void Errors()
        {
            var left  = FSBuilder.Take <UnsignedObject>("|", "A").Else((s, o) => { });
            var right = FSBuilder.Take <UnsignedObject>("|", "B").Else((s, o) => { });

            try
            {
                left.Append(right);
                Assert.Fail("Shouldn't be legal to append two else directives");
            }
            catch (Exception) {  }

            left  = FSBuilder.Skip <UnsignedObject>(1).TakeRest("A");
            right = FSBuilder.Skip <UnsignedObject>(1).TakeRest("B");

            try
            {
                left.Append(right);
                Assert.Fail("Shouldn't be legal to append two take rest directives");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(5, "HelloWorld");
                Assert.Fail("Property does not exist");
            }
            catch (Exception) { }

            // These *shouldn't* throw exceptions
            FSBuilder.Take <UnsignedObject>("|", "A").Seal()("345212", new UnsignedObject());
            FSBuilder.Take <UnsignedObject>(4, "A").Seal()("1", new UnsignedObject());
            FSBuilder.Take <UnsignedObject>(1, "A").Take("|", "B").Seal()("asdf", new UnsignedObject());

            try
            {
                FSBuilder.Skip <UnsignedObject>(1).Back(-4);
                Assert.Fail("Back shouldn't accept negatives");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Skip <UnsignedObject>(-4);
                Assert.Fail("Skip shouldn't accept negatives");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(-4, "A");
                Assert.Fail("Take shouldn't accept negatives");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, "Bad");
                Assert.Fail("Bad should not be deserializable");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, typeof(string).GetMember("Length")[0]);
                Assert.Fail("Length is not on UnsignedObject");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, typeof(UnsignedObject).GetMember("ToString")[0]);
                Assert.Fail("ToString is not a field or property");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, "Hidden");
                Assert.Fail("Hidden is not settable");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, "Static");
                Assert.Fail("Statis is not an instance property");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, "StaticField");
                Assert.Fail("StaticField is not an instance field");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(4, "A", format: "yyyy-mm-dd");
                Assert.Fail("A is not a DateTime or TimeSpan");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(",", "DT", format: "asdf");
                Assert.Fail("DateTime format string is invalid");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(",", "TS", format: "asdf");
                Assert.Fail("TimeSpan format string is invalid");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>(",", "GD", format: "sadf");
                Assert.Fail("Guid format string is invalid");
            }
            catch (Exception) { }

            try
            {
                FSBuilder.Take <UnsignedObject>("", "TS");
                Assert.Fail("An empty until is invalid");
            }
            catch (Exception) { }
        }
Beispiel #13
0
        static Tests()
        {
            var step1 =
                FSBuilder
                .Until <LogRow>(" ");

            var step2 =
                FSBuilder
                .Take <LogRow>(":", "ClientIp")
                .Until("[")
                .Take("]", LogProp("CreationDate"), format: "dd/MMM/yyyy:HH:mm:ss.fff")
                .Until(" ")
                .Take(" ", "FrontEnd")
                .Take("/", LogProp("BackEnd"))
                .Take(" ", "Server")
                .Take("/", LogProp("Tq"))
                .Take("/", "Tw")
                .Take("/", LogProp("Tc"))
                .Take("/", "Tr")
                .Take(" ", LogProp("Tt"))
                .Take(" ", "ResponseCode")
                .Take(" ", LogProp("Bytes"))
                .Until("- ")
                .Until("- ")
                .Take(4, "TermState")
                .Until(" ");

            var step3 =
                FSBuilder
                .Take <LogRow>("/", LogProp("ActConn"))
                .Take("/", "FeConn")
                .Take("/", LogProp("BeConn"))
                .Take("/", "SrvConn")
                .Take(" ", LogProp("Retries"))
                .Take("/", "SrvQueue")
                .Take(" ", LogProp("BackEndQueue"))
                .Until("{")
                .Take("|", "Referer")
                .Take("|", LogProp("UserAgent"))
                .Take("|", "Host")
                .Take("|", LogProp("ForwardFor"))
                .Take("}", "AcceptEncoding")
                .Until("{")
                .Take("|", LogProp("ContentEncoding"))
                .Take("|", "IsPageView")
                .Take("|", LogProp("SqlDurationMs"))
                .Take("|", "AccountId")
                .Take("}", LogProp("RouteName"))
                .Until("\"")
                .Take(" ", "Method")
                .Take(" ", LogProp("Uri"))
                .Take("\"", "HttpVersion");

            FTemplate =
                step1.Append(step2).Append(step3)
                .Else(
                    (str, row) =>
            {
                throw new Exception("Couldn't parse: " + str);
            }
                    )
                .Seal();
        }
Beispiel #14
0
        public void SimpleStringPerf()
        {
            // THIS TEST IS EXPECTED TO FAIL
            //   String performance in the hand written case is *very good*, if you
            //   can gin up better code for this case in the FSP, submit a patch.
            //   It's an interesting project.

            var regex      = new Regex(@"([^,]*?),([^,]*?),([^,]*?),([^,]*)", RegexOptions.Compiled);
            var parserTask =
                FSBuilder
                .Take <StringPerfObject>(",", "A")
                .Take(",", "B")
                .Take(",", "C")
                .TakeRest("D")
                .Seal();

            Action ghettoGC = () => { GC.Collect(); Thread.Sleep(100); };

            Action <string, StringPerfObject> regexTask =
                delegate(string str, StringPerfObject obj)
            {
                var matches = regex.Match(str);

                obj.A = matches.Groups[1].Value;
                obj.B = matches.Groups[2].Value;
                obj.C = matches.Groups[3].Value;
                obj.D = matches.Groups[4].Value;
            };

            Action <string, StringPerfObject> handTask =
                delegate(string str, StringPerfObject obj)
            {
                int a = str.IndexOf(',');
                obj.A = str.Substring(0, a);

                int b = str.IndexOf(',', a + 1);
                obj.B = str.Substring(a + 1, b - (a + 1));

                int c = str.IndexOf(',', b + 1);
                obj.C = str.Substring(b + 1, c - (b + 1));

                obj.D = str.Substring(c + 1, str.Length - (c + 1));
            };

            var rand = new Random();
            var data = new List <string>();

            for (int i = 0; i < 1000000; i++)
            {
                data.Add(Guid.NewGuid() + "," + Guid.NewGuid() + "," + Guid.NewGuid() + "," + Guid.NewGuid());
            }

            // Equivalence check
            foreach (var str in data)
            {
                var o1 = new StringPerfObject();
                var o2 = new StringPerfObject();
                var o3 = new StringPerfObject();

                parserTask(str, o1);
                regexTask(str, o2);
                handTask(str, o3);

                if (o1.A != o2.A || o2.A != o3.A)
                {
                    throw new Exception();
                }
                if (o1.B != o2.B || o2.B != o3.B)
                {
                    throw new Exception();
                }
                if (o1.C != o2.C || o2.C != o3.C)
                {
                    throw new Exception();
                }
                if (o1.D != o2.D || o2.D != o3.D)
                {
                    throw new Exception();
                }
            }

            var results = new Dictionary <int, List <long> >();

            results[0] = new List <long>();   // regex
            results[1] = new List <long>();   // hand
            results[2] = new List <long>();   // parser

            var timer    = new Stopwatch();
            var speedObj = new StringPerfObject();

            for (int i = 0; i < 5; i++)
            {
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    regexTask(str, speedObj);
                }
                timer.Stop();

                results[0].Add(timer.ElapsedMilliseconds);
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    handTask(str, speedObj);
                }
                timer.Stop();

                results[1].Add(timer.ElapsedMilliseconds);
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    parserTask(str, speedObj);
                }
                timer.Stop();

                results[2].Add(timer.ElapsedMilliseconds);
            }

            var medianRegex  = results[0].OrderBy(o => o).ElementAt(results[0].Count / 2);
            var medianHand   = results[1].OrderBy(o => o).ElementAt(results[1].Count / 2);
            var medianParser = results[2].OrderBy(o => o).ElementAt(results[2].Count / 2);

            Assert.IsTrue(medianRegex > medianHand, "Regex faster than hand rolled; invalid test");
            Assert.IsTrue(medianHand > medianParser, "Hand [" + medianHand + "] faster than generated [" + medianParser + "]; bad parser");
        }
Beispiel #15
0
        public void SimpleIntPerf()
        {
            var regex      = new Regex(@"(\d+),(\d+),(\d+),(\d+)", RegexOptions.Compiled);
            var parserTask =
                FSBuilder
                .Take <IntPerfObject>(",", "A")
                .Take(",", "B")
                .Take(",", "C")
                .TakeRest("D")
                .Seal();

            Action ghettoGC = () => { GC.Collect(); Thread.Sleep(100); };

            Action <string, IntPerfObject> regexTask =
                delegate(string str, IntPerfObject obj)
            {
                var matches = regex.Match(str);

                obj.A = int.Parse(matches.Groups[1].Value);
                obj.B = int.Parse(matches.Groups[2].Value);
                obj.C = int.Parse(matches.Groups[3].Value);
                obj.D = int.Parse(matches.Groups[4].Value);
            };

            Action <string, IntPerfObject> handTask =
                delegate(string str, IntPerfObject obj)
            {
                int a = str.IndexOf(',');
                obj.A = int.Parse(str.Substring(0, a));

                int b = str.IndexOf(',', a + 1);
                obj.B = int.Parse(str.Substring(a + 1, b - (a + 1)));

                int c = str.IndexOf(',', b + 1);
                obj.C = int.Parse(str.Substring(b + 1, c - (b + 1)));

                obj.D = int.Parse(str.Substring(c + 1, str.Length - (c + 1)));
            };

            var rand = new Random();
            var data = new List <string>();

            for (int i = 0; i < 1000000; i++)
            {
                data.Add(rand.Next() + "," + rand.Next() + "," + rand.Next() + "," + rand.Next());
            }

            // Equivalence check
            foreach (var str in data)
            {
                var o1 = new IntPerfObject();
                var o2 = new IntPerfObject();
                var o3 = new IntPerfObject();

                parserTask(str, o1);
                regexTask(str, o2);
                handTask(str, o3);

                if (o1.A != o2.A || o2.A != o3.A)
                {
                    throw new Exception();
                }
                if (o1.B != o2.B || o2.B != o3.B)
                {
                    throw new Exception();
                }
                if (o1.C != o2.C || o2.C != o3.C)
                {
                    throw new Exception();
                }
                if (o1.D != o2.D || o2.D != o3.D)
                {
                    throw new Exception();
                }
            }

            var results = new Dictionary <int, List <long> >();

            results[0] = new List <long>();   // regex
            results[1] = new List <long>();   // hand
            results[2] = new List <long>();   // parser

            var timer    = new Stopwatch();
            var speedObj = new IntPerfObject();

            for (int i = 0; i < 5; i++)
            {
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    regexTask(str, speedObj);
                }
                timer.Stop();

                results[0].Add(timer.ElapsedMilliseconds);
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    handTask(str, speedObj);
                }
                timer.Stop();

                results[1].Add(timer.ElapsedMilliseconds);
                ghettoGC();

                timer.Restart();
                foreach (var str in data)
                {
                    parserTask(str, speedObj);
                }
                timer.Stop();

                results[2].Add(timer.ElapsedMilliseconds);
            }

            var medianRegex  = results[0].OrderBy(o => o).ElementAt(results[0].Count / 2);
            var medianHand   = results[1].OrderBy(o => o).ElementAt(results[1].Count / 2);
            var medianParser = results[2].OrderBy(o => o).ElementAt(results[2].Count / 2);

            Assert.IsTrue(medianRegex > medianHand);
            Assert.IsTrue(medianHand > medianParser);
        }