public void CheckJoinTables()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var potatoFields = new List<FieldConfig>
            {
                new FieldConfig("Id", null),
                new FieldConfig("FoobarId", null),
                new FieldConfig("Type", null)
            };
            var foobarRelationship = new ParentConfig ("Foobar", null, null);
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId),
                new OracularTable("Potato", null, new List<ParentConfig>{foobarRelationship}, potatoFields)
            };
            var specs = new List<OracularSpec>();
            var config = new OracularConfig (tables, specs);
            var checker = new RefChecker (config);

            var fingerlingPotatoes = new BinaryOperation("=",
                new Reference(new [] { "Potato", "Type" }),
                new StringLiteral("Fingerling")
            );

            var call = new MacroExpansion(
                new Reference(new [] { "ANY" }),
                new AstNode[] {
                    new Reference(new [] { "Potato" }),
                    fingerlingPotatoes
                }
            );

            var initial = new []{ "Foobar" };

            var result = call.Walk (checker, initial);

            Assert.AreEqual (2, result.Length);
            Assert.Contains ("Foobar", result);
            Assert.Contains ("Potato", result);
        }
        public void ExpectReferenceRootToBeInTables()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var tables = new List<OracularTable>
            {
                new OracularTable("Other", null, null, justAnId),
                new OracularTable("Tables", null, null, justAnId)
            };
            var config = new OracularConfig (tables, new List<OracularSpec> ());
            var checker = new RefChecker (config);

            var reference = new Reference (new []{ "Foobar" });

            var initial = new []{ "Other", "Tables" };

            var ex = Assert.Throws<RefCheckException> (() => reference.Walk (checker, initial));

            Assert.That (JOIN_RE.IsMatch (ex.Message));
        }
        public void ExpectSpecToExist()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId)
            };
            var specs = new List<OracularSpec>();
            var config = new OracularConfig (tables, specs);
            var checker = new RefChecker (config);

            var reference = new Reference (new [] { "Foobar" });
            var fn = new Reference (new [] { "isBaz" });
            var call = new MacroExpansion (fn, new [] { reference });

            var initial = new []{ "Foobar" };

            var ex = Assert.Throws<RefCheckException>(() => call.Walk (checker, initial));

            Assert.That (REFERENCE_RE.IsMatch (ex.Message));
        }
        public void ExpectNestedSpecToRefcheck()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var potatoFields = new List<FieldConfig>
            {
                new FieldConfig("Id", null),
                new FieldConfig("FoobarId", null)
            };
            var foobarRelationship = new ParentConfig ("Foobar", null, null);
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId),
                new OracularTable("Potato", null, new List<ParentConfig>{foobarRelationship}, potatoFields)
            };
            var specs = new List<OracularSpec>();
            var config = new OracularConfig (tables, specs);
            var checker = new RefChecker (config);

            var fingerlingPotatoes = new MacroExpansion(
                new Reference(new [] { "isFingerling" }),
                new [] { new Reference(new [] { "Potato" }) }
            );

            var call = new MacroExpansion(
                new Reference(new [] { "ANY" }),
                new AstNode[] {
                    new Reference(new [] { "Potato" }),
                    fingerlingPotatoes
                }
            );

            var initial = new []{ "Foobar" };

            var ex = Assert.Throws<RefCheckException> (() => call.Walk (checker, initial));

            Assert.That (REFERENCE_RE.IsMatch (ex.Message));
        }
        public void ExpectJoinTableToExist()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId)
            };
            var specs = new List<OracularSpec>();
            var config = new OracularConfig (tables, specs);
            var checker = new RefChecker (config);

            var fingerlingPotatoes = new BinaryOperation("=",
                new Reference(new [] { "Potato", "Type" }),
                new StringLiteral("Fingerling")
            );

            var call = new MacroExpansion(
                new Reference(new [] { "ANY" }),
                new [] { fingerlingPotatoes }
            );

            var initial = new []{ "Foobar" };

            var ex = Assert.Throws<RefCheckException> (() => call.Walk (checker, initial));

            Assert.That (REFERENCE_RE.IsMatch (ex.Message));
        }
        public void CheckSpecReferences()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId)
            };
            var specs = new List<OracularSpec>
            {
                new OracularSpec("isBaz", "Foobar", "Foobar.Id != null")
            };
            var config = new OracularConfig (tables, specs);
            var checker = new RefChecker (config);

            var reference = new Reference (new [] { "Foobar" });
            var fn = new Reference (new [] { "isBaz" });
            var call = new MacroExpansion (fn, new [] { reference });

            var initial = new []{ "Foobar" };

            var result = call.Walk (checker, initial);

            Assert.AreEqual (1, result.Length);
            Assert.Contains ("Foobar", result);
        }
        public void CheckReferenceRoot()
        {
            var justAnId = new List<FieldConfig>
            {
                new FieldConfig("Id", null)
            };
            var tables = new List<OracularTable>
            {
                new OracularTable("Foobar", null, null, justAnId)
            };
            var config = new OracularConfig (tables, new List<OracularSpec> ());
            var checker = new RefChecker (config);

            var reference = new Reference (new []{ "Foobar" });

            var initial = new []{ "Foobar" };

            var result = reference.Walk (checker, initial);

            Assert.AreEqual (1, result.Length);
            Assert.Contains ("Foobar", result);
        }
        public void Check()
        {
            var typechecker = new TypeChecker (this);
            foreach (var spec in specs.Values)
            {
                spec.Spec.Walk (typechecker);
            }

            var refchecker = new RefChecker (this);
            foreach (var spec in specs.Values)
            {
                spec.Spec.Walk (refchecker, new [] { spec.Table });
            }
        }