public void Parse_Concurrency_ThrowsNodeConcurrencyException()
        {
            // Arrange
            INodeFamily nodeFamily = new NodeFamily("family");
            INode       idle       = new IdleNode(nodeFamily, null);
            INode       exactText  = new ExactTextNode(
                "foo",
                new[] { WordTextClass.Instance, },
                false,
                (node, token, arg3) => { },
                nodeFamily,
                null);
            INode someText = new TextNode(
                new ITextClass[] { WordTextClass.Instance, },
                null,
                nodeFamily,
                null);

            idle.EstablishLink(someText);
            idle.EstablishLink(exactText);
            someText.EstablishLink(EndNode.Instance);
            exactText.EstablishLink(EndNode.Instance);

            IParser parser = new Parser();

            var tokens = new List <IToken>
            {
                new TextToken(
                    WordTextClass.Instance,
                    NoneTextDecoration.Instance,
                    "foo",
                    Position.Zero,
                    3),
            };

            // Act
            parser.Root = idle;
            var ex = Assert.Throws <NodeConcurrencyException>(() => parser.Parse(tokens));

            // Assert
            Assert.That(ex.Message, Is.EqualTo("More than one node accepted the token."));
            Assert.That(ex.ConcurrentNodes, Has.Length.EqualTo(2));
            Assert.That(ex.ConcurrentNodes, Does.Contain(exactText));
            Assert.That(ex.ConcurrentNodes, Does.Contain(someText));
            Assert.That(ex.Token, Is.SameAs(tokens.Single()));
        }
Exemple #2
0
        protected override INode CreateNodeTree()
        {
            var addIns = this.CreateAddIns();

            if (addIns == null)
            {
                throw new CliException($"'{nameof(CreateAddIns)}' must not return null.");
            }

            if (addIns.Count == 0)
            {
                _addInList = new List <ICliAddIn>();
                var dummyRoot = new IdleNode(_nodeFamily, $"Dummy root node of empty host '{this.Name}'");
                dummyRoot.EstablishLink(EndNode.Instance);

                return(dummyRoot);
            }

            var validTypes = addIns.All(x => x is CliAddInBase);

            if (!validTypes)
            {
                throw new CliException($"'{nameof(CreateAddIns)}' must return instances of type '{typeof(CliAddInBase).FullName}'.");
            }

            if (addIns.Any(x => x.Name == null))
            {
                if (addIns.Count > 1)
                {
                    throw new CliException($"'{nameof(CreateAddIns)}' must return either all add-ins having non-null name, or exactly one add-in with null name.");
                }

                var singleUnnamedAddIn = addIns.Single();
                _singleUnnamedAddInRecord = new AddInRecord(singleUnnamedAddIn, singleUnnamedAddIn.GetExecutors());
            }

            foreach (var addIn in addIns)
            {
                ((CliAddInBase)addIn).Host = this;
            }

            var root = new IdleNode(_nodeFamily, $"Root node of host '{this.Name}'");

            if (_singleUnnamedAddInRecord == null)
            {
                // all add-ins are named
                foreach (var addIn in addIns)
                {
                    root.EstablishLink(addIn.Node);

                    var record = new AddInRecord(
                        addIn,
                        addIn.GetExecutors());
                    _addInRecords.Add(addIn.Name, record);
                }

                _addInList = _addInRecords
                             .Values
                             .Select(x => x.AddIn)
                             .ToList();
            }
            else
            {
                root.EstablishLink(_singleUnnamedAddInRecord.AddIn.Node);

                _addInList = new List <ICliAddIn>
                {
                    _singleUnnamedAddInRecord.AddIn,
                };
            }

            return(root);
        }