public void CanDetectDuplicateFields()
        {
            //template with duplicate fields
            var template = @"
            {
              ""Inherits"": [],
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              },
              ""Inherits"": [""A""]              
            }
            ";

            var lexer  = new EntityTemplateLexer(new AntlrInputStream(template));
            var parser = new EntityTemplateParser(new CommonTokenStream(lexer))
            {
                ErrorHandler = new BailErrorStrategy()
            };

            var validationVisitor = new EntityTemplateValidatorVisitor();
            var ast = parser.template();

            Assert.False(validationVisitor.Visit(ast));
            Assert.Single(validationVisitor.DuplicateFields);
            Assert.Contains(validationVisitor.DuplicateFields, x => x == "Inherits");
        }
        public void CanDetectNonObjectNonMandatoryRootFields()
        {
            //template with duplicate fields
            var template = @"
            {
              ""Inherits"": [],
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              },
              ""Foo"": 100.0,
              ""FooBar"" : { ""Health"": 100.0 },
              ""Bar"": [""A""]              
            }
            ";

            var lexer  = new EntityTemplateLexer(new AntlrInputStream(template));
            var parser = new EntityTemplateParser(new CommonTokenStream(lexer))
            {
                ErrorHandler = new BailErrorStrategy()
            };

            var validationVisitor = new EntityTemplateValidatorVisitor();
            var ast = parser.template();

            Assert.False(validationVisitor.Visit(ast));
            Assert.Equal(2, validationVisitor.NonObjectFieldKeys.Count());
            Assert.Contains(validationVisitor.NonObjectFieldKeys, x => x == "Foo" || x == "Bar");
        }
        public void CanDetectDuplicateFieldsInDifferentContexts()
        {
            var template = @"
            {
              ""Id"": ""object"",
              ""Inherits"": [],
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              }
            }
            ";

            var template2 = @"
            {
              ""Id"": ""object"",
              ""Inherits"": [],
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              },
              ""Id"": ""object""
            }
            ";

            var lexer  = new EntityTemplateLexer(new AntlrInputStream(template));
            var parser = new EntityTemplateParser(new CommonTokenStream(lexer))
            {
                ErrorHandler = new BailErrorStrategy()
            };

            var validationVisitor = new EntityTemplateValidatorVisitor();
            var ast = parser.template();

            Assert.True(validationVisitor.Visit(ast));

            Assert.Empty(validationVisitor.DuplicateFields);
            lexer.SetInputStream(new AntlrInputStream(template2));
            parser.SetInputStream(new CommonTokenStream(lexer));
            var ast2 = parser.template();

            validationVisitor.Reset();
            Assert.False(validationVisitor.Visit(ast2));
            Assert.Single(validationVisitor.DuplicateFields);
            Assert.Contains(validationVisitor.DuplicateFields, x => x == "Id");
        }
        public void CanVerifyMandatoryFields()
        {
            //with mandatory fields present
            var template1 = @"
            {
              ""Id"": ""object"",
              ""Inherits"": [],
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              }
            }
            ";

            //with some mandatory fields missing
            var template2 = @"
            {
              ""Id"": ""object"",
              ""Components"": {
                ""Health"": 100.0,
                ""Inherits"": [""A""]
              }
            }
            ";

            //with all mandatory fields missing
            var template3 = @"
            {
              ""Foo"": ""Bar"",
              ""Bar"": ""Foo""
            }
            ";

            var lexer  = new EntityTemplateLexer(new AntlrInputStream(template1));
            var parser = new EntityTemplateParser(new CommonTokenStream(lexer))
            {
                ErrorHandler = new BailErrorStrategy()
            };
            var validationVisitor = new EntityTemplateValidatorVisitor();
            var ast1 = parser.template();

            Assert.True(validationVisitor.Visit(ast1));
            Assert.True(validationVisitor.HasComponentsField);
            Assert.True(validationVisitor.HasIdentifierField);
            Assert.True(validationVisitor.HasInheritsField);

            lexer.SetInputStream(new AntlrInputStream(template2));
            parser.SetInputStream(new CommonTokenStream(lexer));
            var ast2 = parser.template();

            validationVisitor.Reset();
            Assert.False(validationVisitor.Visit(ast2));
            Assert.True(validationVisitor.HasComponentsField);
            Assert.True(validationVisitor.HasIdentifierField);
            Assert.False(validationVisitor.HasInheritsField);

            lexer.SetInputStream(new AntlrInputStream(template3));
            parser.SetInputStream(new CommonTokenStream(lexer));
            var ast3 = parser.template();

            validationVisitor.Reset();
            Assert.False(validationVisitor.Visit(ast3));
            Assert.False(validationVisitor.HasComponentsField);
            Assert.False(validationVisitor.HasIdentifierField);
            Assert.False(validationVisitor.HasInheritsField);
        }