public void t09_Parse_ClassDiagram_Containing_Two_Associated_Classes_With_Roles()
        {
            var tokens = new ClassDiagramTokenStream {
                TokenType.BracketOpen.Token(), "a".Token(), TokenType.BracketClose.Token(),
                "-".Token(), "associationName".Token(), ">".Token(),
                TokenType.BracketOpen.Token(), "b".Token(), TokenType.BracketClose.Token(),
            };

            var parser = new ClassDiagramParser(tokens);
            var cd     = parser.ParseClassDiagram();

            Assert.IsNotNull(cd, "parsing failed");

            var classes = cd.Classes.ToList();

            Assert.AreEqual(2, classes.Count, "wrong class count");
            Assert.AreEqual("a", classes[0].Name, "unexpected class name");
            Assert.AreEqual("b", classes[1].Name, "unexpected class name");

            var assocs = cd.Associations.ToList();

            Assert.AreEqual(1, assocs.Count, "wrong association count");
            Assert.AreEqual("a", assocs[0].Source.Name, "Source name wrong");
            Assert.AreEqual("b", assocs[0].Target.Name, "Target name wrong");
            Assert.AreEqual(AssociationKind.Directed, assocs[0].Kind, "wrong association kind");
            Assert.AreEqual("associationName", assocs[0].TargetRole, "unexpected target role");
        }
        public static ClassDiagramTokenStream FromStrings(params string[] tokens)
        {
            var s = new ClassDiagramTokenStream();

            tokens.Where(s1 => s1.Length > 0).ForEach(t => s.Add(t.Token()));
            return(s);
        }
        public void t08_Parse_ClassDiagram_Containing_Two_Associated_Classes_With_Multiplicities_Numbers(string sourceFrom, string sourceTo, string targetFrom, string targetTo)
        {
            var tokens = new ClassDiagramTokenStream();

            tokens.AddRange(TokenStreamBuilder.Class("a"));

            tokens.AddRange(new[] { sourceFrom.Token() });
            if (sourceTo != null)
            {
                tokens.AddRange(new[] { "..".Token(), sourceTo.Token() });
            }

            tokens.AddRange(new[] { TokenType.Dash.Token() });

            tokens.AddRange(new[] { targetFrom.Token() });
            if (targetTo != null)
            {
                tokens.AddRange(new[] { "..".Token(), targetTo.Token() });
            }

            tokens.AddRange(TokenStreamBuilder.Class("b"));

            var parser = new ClassDiagramParser(tokens);
            var cd     = parser.ParseClassDiagram();
            var assoc  = t08_check(cd);

            checkMultiplicityKind(assoc.SourceMultiplicity.FromKind, sourceFrom, "source from");
            checkMultiplicityKind(assoc.SourceMultiplicity.ToKind, sourceTo, "source to");
            checkMultiplicityKind(assoc.TargetMultiplicity.FromKind, targetFrom, "target from");
            checkMultiplicityKind(assoc.TargetMultiplicity.ToKind, targetTo, "target to");

            Assert.AreEqual(sourceFrom, assoc.SourceMultiplicity.From, "source wrong value");
            Assert.AreEqual(targetFrom, assoc.TargetMultiplicity.From, "target wrong value");
        }
        public void t07_Parse_ClassDiagram_Containing_Two_Associated_Classes_Aggregation()
        {
            var tokens = new ClassDiagramTokenStream {
                TokenType.BracketOpen.Token(), "a".Token(), TokenType.BracketClose.Token(),
                TokenType.Plus.Token(), TokenType.Dash.Token(), TokenType.AngleClose.Token(),
                TokenType.BracketOpen.Token(), "b".Token(), TokenType.BracketClose.Token(),
            };

            t07_Parse_ClassDiagram_Containing_Two_Associated_Classes(tokens, AssociationKind.Aggregation);
        }
        public void t07_Parse_ClassDiagram_Containing_Two_Associated_Classes_Undirected()
        {
            var tokens = new ClassDiagramTokenStream {
                TokenType.BracketOpen.Token(), "a".Token(), TokenType.BracketClose.Token(),
                TokenType.Dash.Token(),
                TokenType.BracketOpen.Token(), "b".Token(), TokenType.BracketClose.Token(),
            };

            t07_Parse_ClassDiagram_Containing_Two_Associated_Classes(tokens, AssociationKind.Undirected);
        }
        public static ClassDiagramTokenStream CombineTokenStreams(params ClassDiagramTokenStream[] streams)
        {
            var combinedStream = new ClassDiagramTokenStream();

            foreach (var singleStream in streams)
            {
                if (singleStream != null)
                {
                    combinedStream.AddRange(singleStream);
                }
            }
            return(combinedStream);
        }
        public void t06_Parse_ClassDiagram_Containing_Two_Classes()
        {
            var tokens = new ClassDiagramTokenStream {
                TokenType.BracketOpen.Token(), "a".Token(), TokenType.BracketClose.Token(),
                TokenType.Comma.Token(),
                TokenType.BracketOpen.Token(), "b".Token(), TokenType.BracketClose.Token(),
            };
            var parser = new ClassDiagramParser(tokens);
            var cd     = parser.ParseClassDiagram();

            Assert.IsNotNull(cd, "parsing failed");

            var classes = cd.Classes.ToList();

            Assert.AreEqual(2, classes.Count, "wrong class count");
            Assert.AreEqual("a", classes[0].Name, "unexpected class name");
            Assert.AreEqual("b", classes[1].Name, "unexpected class name");
        }
        public static ClassDiagramTokenStream Association(string sourceFrom, string sourceTo, string association, string targetFrom, string targetTo)
        {
            var tokens = new ClassDiagramTokenStream();

            tokens.AddRange(new[] { sourceFrom.Token() });
            if (sourceTo != null)
            {
                tokens.AddRange(new[] { "..".Token(), sourceTo.Token() });
            }

            tokens.AddRange(PureAssociation(association));

            tokens.AddRange(new[] { targetFrom.Token() });
            if (targetTo != null)
            {
                tokens.AddRange(new[] { "..".Token(), targetTo.Token() });
            }

            return(tokens);
        }
        public static ClassDiagramTokenStream Field(string name, string type = null, string accessModifier = null)
        {
            var stream = new ClassDiagramTokenStream {
                name.Token()
            };

            if (type != null)
            {
                stream = CombineTokenStreams(stream, new ClassDiagramTokenStream {
                    TokenType.Colon.Token(), type.Token()
                });
            }
            if (accessModifier != null)
            {
                stream = CombineTokenStreams(new ClassDiagramTokenStream {
                    accessModifier.Token()
                }, stream);
            }
            return(stream);
        }
        private void t07_Parse_ClassDiagram_Containing_Two_Associated_Classes(ClassDiagramTokenStream genericTokens, AssociationKind expectedKind)
        {
            var parser = new ClassDiagramParser(genericTokens);
            var cd     = parser.ParseClassDiagram();

            Assert.IsNotNull(cd, "parsing failed");

            var classes = cd.Classes.ToList();

            Assert.AreEqual(2, classes.Count, "wrong class count");
            Assert.AreEqual("a", classes[0].Name, "unexpected class name");
            Assert.AreEqual("b", classes[1].Name, "unexpected class name");

            var assocs = cd.Associations.ToList();

            Assert.AreEqual(1, assocs.Count, "wrong association count");
            Assert.AreEqual("a", assocs[0].Source.Name, "Source name wrong");
            Assert.AreEqual("b", assocs[0].Target.Name, "Target name wrong");
            Assert.AreEqual(expectedKind, assocs[0].Kind, "wrong association kind");
        }
        public static ClassDiagramTokenStream Class(string className, ClassDiagramTokenStream fields = null, ClassDiagramTokenStream methods = null)
        {
            var f = CombineTokenStreams(new ClassDiagramTokenStream {
                TokenType.Pipe.Token()
            }, fields);
            var m = CombineTokenStreams(new ClassDiagramTokenStream {
                TokenType.Pipe.Token()
            }, methods);

            var ts = CombineTokenStreams(
                new ClassDiagramTokenStream {
                TokenType.BracketOpen.Token(), className.Token()
            },
                fields == null ? (methods != null ? new ClassDiagramTokenStream {
                TokenType.Pipe.Token()
            } : null) : f,
                methods == null ? null : m,
                new ClassDiagramTokenStream {
                TokenType.BracketClose.Token(),
            }
                );

            return(ts);
        }
        public static ClassDiagramTokenStream Method(string name, string visibilityModifier = "+", ClassDiagramTokenStream parameterStream = null)
        {
            var stream = CombineTokenStreams(
                new ClassDiagramTokenStream {
                visibilityModifier.Token(), name.Token(), TokenType.ParenthesisOpen.Token()
            },
                parameterStream,
                new ClassDiagramTokenStream {
                TokenType.ParenthesisClose.Token()
            }
                );

            return(stream);
        }
        private static Action <IParseErrorHandler> RetrieveErrorCallback(TestData data, ClassDiagramTokenStream tokens)
        {
            Action <IParseErrorHandler> callback;

            switch (data.Target)
            {
            case ParseTarget.ClassDiagram:
                callback = ec => tokens.ParseClassDiagram(ec);
                break;

            default:
                throw new ArgumentException("don't know how to handle " + data.Target.ToString());
            }
            return(callback);
        }
 internal static IClassDiagram ParseClassDiagram(this ClassDiagramTokenStream classDiagramTokenStream, IParseErrorHandler parseErrorHandler = null)
 {
     return(new ClassDiagramParser(classDiagramTokenStream, parseErrorHandler).ParseClassDiagram());
 }