Пример #1
0
        public Member(Env env, Composite parent, string name, Type type)
        {
            // In this function, we must fully define what type we are (important in the case of Dec or containers)
            // and also set our default value (if relevant.)

            this.parent = parent;
            this.name   = name;
            this.type   = type;

            if (type == Type.Composite)
            {
                if (parent.type == Composite.Type.Struct)
                {
                    // We only want to include structs that happen after us in the type list
                    var structs = env.types.SkipWhile(etype => etype != parent).Skip(1).Where(etype => etype.type == Composite.Type.Struct);
                    var classes = env.types.Where(etype => etype.type == Composite.Type.Class);
                    compositeChild = structs.Concat(classes).RandomElement();
                }
                else
                {
                    compositeChild = env.types.Where(etype => etype.type != Composite.Type.Dec).RandomElement();
                }

                if (parent.type == Composite.Type.Struct)
                {
                    initialized = null; // won't be used anywhere anyway, just fall back on defaults
                }
                else
                {
                    initialized = new ValueComposite(env, compositeChild);
                }
            }
            else if (type == Type.Dec)
            {
                compositeChild = env.types.Where(inst => inst.type == Composite.Type.Dec).RandomElement();
                initialized    = new ValueSimple("null", "");
            }
            else if (type == Type.ContainerList)
            {
                containerValue = new Member(env, parent, null, MemberTypeDistribution.Distribution.Choose());
                initialized    = new ValueSimple("null", "");
            }
            else if (type == Type.ContainerDictionary)
            {
                containerKey   = new Member(env, parent, null, MemberTypeDistribution.DictKeyDistribution.Choose());
                containerValue = new Member(env, parent, null, MemberTypeDistribution.Distribution.Choose());
                initialized    = new ValueSimple("null", "");
            }
            else if (parent.type == Composite.Type.Struct)
            {
                // structs always init to basic types
                if (type == Type.String || type == Type.Composite && this.compositeChild.type != Composite.Type.Struct)
                {
                    initialized = new ValueSimple("null");
                }
                else if (type == Type.Bool)
                {
                    initialized = new ValueSimple("false");
                }
                else if (type != Type.Composite)
                {
                    initialized = new ValueSimple("0");
                }

                // otherwise it's a struct composite and we don't really have anything sensible to compare it to
            }
            else
            {
                initialized = GenerateValue(env);
            }
        }
Пример #2
0
        private static void Main()
        {
            Init();

            var env = new Env();

            // Generate initial composites
            for (int i = 0; i < 100; ++i)
            {
                var c = new Composite();
                c.name = Rand.NextString();

                c.type = CompositeTypeDistribution.Distribution.Choose();
                if (c.type == Composite.Type.Dec)
                {
                    c.name += "Dec";
                }

                env.types.Add(c);
            }

            // Generate parameters
            foreach (var c in env.types)
            {
                int parameterCount = Rand.WeightedDistribution();

                for (int i = 0; i < parameterCount; ++i)
                {
                    c.members.Add(new Member(env, c, Rand.NextString(), MemberTypeDistribution.Distribution.Choose()));
                }
            }

            // Generate instances
            foreach (var c in env.types)
            {
                if (c.type != Composite.Type.Dec)
                {
                    continue;
                }

                int creations = Rand.WeightedDistribution();
                for (int i = 0; i < creations; ++i)
                {
                    env.instances.Add(new Instance(env, c));
                }
            }

            string GenerateTestHarness(string testData)
            {
                string testHarness = File.ReadAllText("data/TestHarness.cs.template");

                var csComposites = new StringBuilder();

                foreach (var c in env.types)
                {
                    csComposites.Append(Util.Indent(c.WriteCsharpDefinition(), 2));
                }

                var types    = string.Join(", ", env.types.Select(c => $"typeof({c.name})"));
                var filename = "data/Fuzzgen.FuzzgenTest.xml";

                return(testHarness
                       .Replace("<<COMPOSITES>>", csComposites.ToString())
                       .Replace("<<TYPES>>", types)
                       .Replace("<<FILENAME>>", $"\"{filename}\"")
                       .Replace("<<TESTS>>", testData));
            }

            string testCode = GenerateTestHarness("");

            string xmlCode;

            // Output xml
            {
                var sb = new StringBuilder();
                sb.AppendLine("<Decs>");

                foreach (var i in env.instances)
                {
                    sb.AppendLine(Util.Indent(i.WriteXmlDec()));
                }

                sb.AppendLine("</Decs>");

                xmlCode = sb.ToString();
            }

            // This is a bit janky; we want to use Dec features when doing generation, but now we need to blow it away to generate the .cs code
            // So I guess maybe it would be nice to have non-global state right now :V

            Dec.Database.Clear();

            var bootstrapAssembly = DecUtilLib.Compilation.Compile(testCode, new System.Reflection.Assembly[] { });

            bootstrapAssembly.GetType("DecTest.Harness").GetMethod("Setup").Invoke(null, null);

            var parser = new Dec.Parser();

            parser.AddString(xmlCode);
            parser.Finish();

            var composer = new Dec.Composer();
            var tests    = composer.ComposeValidation();

            string finalCode = GenerateTestHarness(tests);

            string path = $"../../test/data/golden/parser/{System.DateTimeOffset.Now:yyyyMMddhhmmss}";

            System.IO.Directory.CreateDirectory(path);

            DecUtilLib.Compress.WriteToFile(System.IO.Path.Combine(path, "Harness.cs"), finalCode);
            DecUtilLib.Compress.WriteToFile(System.IO.Path.Combine(path, "data.xml"), xmlCode);
        }