public void ScanComplexFile()
        {
            using(Stream resourceStream = 
                Assembly.GetExecutingAssembly().GetManifestResourceStream("octalforty.Wizardby.Tests.Resources.Waffle.mdl"))
            {
                IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StreamReader(resourceStream, Encoding.UTF8)));
                mdlScanner.RegisterKeyword("migration");
                mdlScanner.RegisterKeyword("default");
                mdlScanner.RegisterKeyword("create");
                mdlScanner.RegisterKeyword("table");

                TokenSequence tokens = mdlScanner.Scan();

                Assert.Greater(tokens.Count, 0);
            } // using
        }
        public IDeploymentInfo ParseDeploymentInfo(StreamReader streamReader)
        {
            MdlScanner scanner = new MdlScanner(new SourceReader(streamReader));
            scanner.RegisterKeyword("deployment");
            scanner.RegisterKeyword("environment");

            IMdlParser mdlParser = new MdlParser(scanner);

            IDeploymentNode deploymentNode = (IDeploymentNode)mdlParser.Parse();
            EnvironmentCollection environments = new EnvironmentCollection();

            foreach(IEnvironmentNode environmentNode in deploymentNode.ChildNodes)
            {
                environments.Add(ParseEnvironment(environmentNode));
            } // foreach

            return new DeploymentInfo(environments);
        }
        public void ScanKeywords()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("migration \"Waffle\" revision => 1 default create table")));
            mdlScanner.RegisterKeyword("migration");
            mdlScanner.RegisterKeyword("default");
            mdlScanner.RegisterKeyword("create");
            mdlScanner.RegisterKeyword("table");

            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(9, tokens.Count);
            Assert.AreEqual(new Token(TokenType.Keyword, "migration", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.StringConstant, "Waffle", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "revision", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.PropertyAssignment, "=>", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "1", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Keyword, "default", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Keyword, "create", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Keyword, "table", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }
        public static IMdlScanner CreateScanner(TextReader textReader)
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(textReader));
            mdlScanner.RegisterKeyword("migration");
            mdlScanner.RegisterKeyword("deployment");
            mdlScanner.RegisterKeyword("type-aliases");
            mdlScanner.RegisterKeyword("type-alias");
            mdlScanner.RegisterKeyword("environment");
            mdlScanner.RegisterKeyword("defaults");
            mdlScanner.RegisterKeyword("default-primary-key");
            mdlScanner.RegisterKeyword("baseline");
            mdlScanner.RegisterKeyword("version");
            mdlScanner.RegisterKeyword("add");
            mdlScanner.RegisterKeyword("remove");
            mdlScanner.RegisterKeyword("table");
            mdlScanner.RegisterKeyword("column");
            mdlScanner.RegisterKeyword("index");
            mdlScanner.RegisterKeyword("reference");
            mdlScanner.RegisterKeyword("alter");
            mdlScanner.RegisterKeyword("templates");
            mdlScanner.RegisterKeyword("template");
            mdlScanner.RegisterKeyword("refactor");
            mdlScanner.RegisterKeyword("constraint");
            mdlScanner.RegisterKeyword("execute");
            mdlScanner.RegisterKeyword("native-sql");
            mdlScanner.RegisterKeyword("schema");
            mdlScanner.RegisterKeyword(MdlSyntax.IncludeTemplate);

            return mdlScanner;
        }
 public void RegisterKeywordThrowsArgumentExceptionOnEmptyKeyword()
 {
     IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("migration \"Waffle\" revision => 1 default create table")));
     mdlScanner.RegisterKeyword("");
 }
        public void ScanBlocks()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader(
@"migration revision => 1:
    baseline:
        create table Hi
        create table There")));
            TokenSequence tokens = mdlScanner.Scan();
            
            Assert.AreEqual(21, tokens.Count);

            Assert.AreEqual(new Token(TokenType.Symbol, "migration", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "revision", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.PropertyAssignment, "=>", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "1", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.BeginBlock, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "baseline", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.BeginBlock, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "create", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "table", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "Hi", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "create", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "table", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "There", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndBlock, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndBlock, "", null), tokens.RemoveFirst());
        }
        public void ScanBlocksWithWeirdLayout()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader(
@"migration revision => 1:" + System.Environment.NewLine +
"       " + System.Environment.NewLine +
@"    baseline:" + System.Environment.NewLine +
"           " + System.Environment.NewLine +
"       /*        */" + System.Environment.NewLine +
"   " + System.Environment.NewLine +
"        create table Hi" + System.Environment.NewLine +
"   " + System.Environment.NewLine +
"           " + System.Environment.NewLine +
"        create table There" + System.Environment.NewLine +
"" + System.Environment.NewLine +
"   " + System.Environment.NewLine +
"" + System.Environment.NewLine +
"" + System.Environment.NewLine)));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(21, tokens.Count);

            Assert.AreEqual(new Token(TokenType.Symbol, "migration", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "revision", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.PropertyAssignment, "=>", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "1", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            
            Token endStatementToken = tokens.RemoveFirst();
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), endStatementToken);
            Assert.Greater(endStatementToken.Location.Column, 0);

            Token beginBlockToken = tokens.RemoveFirst();
            Assert.AreEqual(new Token(TokenType.BeginBlock, "", null), beginBlockToken);
            Assert.Greater(beginBlockToken.Location.Column, 0);

            Assert.AreEqual(new Token(TokenType.Symbol, "baseline", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.BeginBlock, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "create", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "table", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "Hi", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "create", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "table", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "There", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, "", null), tokens.RemoveFirst());
            
            Token endBlockToken = tokens.RemoveFirst();
            Assert.AreEqual(new Token(TokenType.EndBlock, "", null), endBlockToken);
            Assert.AreEqual(new Token(TokenType.EndBlock, "", null), tokens.RemoveFirst());
        }
        public void ScanUpdatesLocations()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("\"abc\" \"cde\\\"fg\\\"h\" \"\"" +
                System.Environment.NewLine + "hit -123 0 1   ")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(9, tokens.Count);
            Assert.AreEqual(new Location(0, 0), tokens.RemoveFirst().Location);
            Assert.AreEqual(new Location(0, 6), tokens.RemoveFirst().Location);
            
            tokens.RemoveFirst();
            tokens.RemoveFirst();
            
            Assert.AreEqual(new Location(1, 0), tokens.RemoveFirst().Location);
            Assert.AreEqual(new Location(1, 4), tokens.RemoveFirst().Location);
        }
        public void ScanNestedComments()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("/* high-velocity /*bullet_/*a/*t*/*/ close.range*/ candamage*/")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(0, tokens.Count);
        }
        public void ScanSymbolsWithMultilineComments()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("high-velocity /*bullet_at" + 
                System.Environment.NewLine + "close.*/range candamage")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(4, tokens.Count);
            Assert.AreEqual(new Token(TokenType.Symbol, "high-velocity", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "range", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "candamage", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }
        public void ScanSymbols()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("high-velocity bullet_at close.range candamage")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(5, tokens.Count);
            Assert.AreEqual(new Token(TokenType.Symbol, "high-velocity", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "bullet_at", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "close.range", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Symbol, "candamage", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }
        public void ScanStringConstants()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("\"abc\" \"cde\\\"fg\\\"h\" \"\"")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(4, tokens.Count);
            Assert.AreEqual(new Token(TokenType.StringConstant, "abc", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.StringConstant, "cde\\\"fg\\\"h", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.StringConstant, "", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }
        public void ScanIntegerConstants()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader("123 -123 0 1")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(5, tokens.Count);
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "123", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "-123", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "0", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.IntegerConstant, "1", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }
        public void ScanPunctuation()
        {
            IMdlScanner mdlScanner = new MdlScanner(new SourceReader(new StringReader(": : => [[, ] ] {,} { } (( )")));
            TokenSequence tokens = mdlScanner.Scan();

            Assert.AreEqual(17, tokens.Count);
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Colon, ":", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.PropertyAssignment, "=>", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftSquareBracket, "[", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftSquareBracket, "[", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Comma, ",", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.RightSquareBracket, "]", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.RightSquareBracket, "]", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftBrace, "{", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.Comma, ",", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.RightBrace, "}", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftBrace, "{", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.RightBrace, "}", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftBracket, "(", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.LeftBracket, "(", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.RightBracket, ")", null), tokens.RemoveFirst());
            Assert.AreEqual(new Token(TokenType.EndStatement, null), tokens.RemoveFirst());

            Assert.AreEqual(0, tokens.Count);
        }