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())); }
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); }