예제 #1
0
 public void TestDuplicateRecursive()
 {
     Node child = new Node { Key = 17 };
     Node parent = new Node { Nodes = new[] { child, child, child } };
     child.Nodes = new[] { parent };
     VerifyNodeTree(parent);
 }
예제 #2
0
 // [Test] known variation...
 public void TestEmptyArray()
 {
     Node node = new Node
     {
         Key = 27,
         Nodes = new Node[0]
     };
     VerifyNodeTree(node);
 }
예제 #3
0
        static bool AreEqual(Node x, Node y, out string msg)
        {
            // compare core
            if (ReferenceEquals(x, y)) { msg = ""; return true; }
            if (x == null || y == null) { msg = "1 node null"; return false; }
            if (x.Key != y.Key) { msg = "key"; return false; }

            Node[] xNodes = x.Nodes, yNodes = y.Nodes;
            if (ReferenceEquals(xNodes,yNodes))
            { // trivial
            }
            else
            {
                if (xNodes == null || yNodes == null) { msg = "1 Nodes null"; return false; }
                if (xNodes.Length != yNodes.Length) { msg = "Nodes length"; return false; }
                for (int i = 0; i < xNodes.Length; i++)
                {
                    bool eq = AreEqual(xNodes[i], yNodes[i], out msg);
                    if (!eq)
                    {
                        msg = i.ToString() + "; " + msg;
                        return false;
                    }
                }
            }
            // run out of things to be different!
            msg = "";
            return true;

        }
예제 #4
0
 static void VerifyNodeTree(Node node) {
     Node clone = Serializer.DeepClone(node);
     string msg;
     bool eq = AreEqual(node, clone, out msg);
     Assert.IsTrue(eq, msg);
 }
예제 #5
0
 public void TestNestedArray()
 {
     Node node = new Node
     {
         Key = 27,
         Nodes = new[] {
             new Node {
                 Key = 19,
                 Nodes = new[] {
                     new Node {Key = 1},
                     new Node {Key = 14},
                 },
             },
             new Node {
                 Key = 3
             },
             new Node {
                 Key = 3,
                 Nodes = new[] {
                     new Node {Key = 234}
                 }
             }
         }
     };
     VerifyNodeTree(node);
 }
예제 #6
0
 public void TestNullArray()
 {
     Node node = new Node
     {
         Key = 27,
         Nodes = null
     };
     VerifyNodeTree(node);
 }
예제 #7
0
 public void TestObjectArray()
 {
     Node node = new Node
     {
         Key = 27,
         Nodes = new[] {
             new Node { Key = 1 },
             new Node { Key = 3 } }
     };
     VerifyNodeTree(node);
 }
        /// <summary>
        /// Removes nodes from start up to but not including the end node.
        /// Start and end are assumed to have the same parent.
        /// </summary>
        private static void RemoveSameParent(Node startNode, Node endNode)
        {
            if ((endNode != null) && (startNode.ParentNode != endNode.ParentNode))
                throw new ArgumentException("Start and end nodes are expected to have the same parent.");

            Node curChild = startNode;
            while ((curChild != null) && (curChild != endNode))
            {
                Node nextChild = curChild.NextSibling;
                curChild.Remove();
                curChild = nextChild;
            }
        }
        /// <summary>
        /// Retrieves text from start up to but not including the end node.
        /// </summary>
        private static string GetTextSameParent(Node startNode, Node endNode)
        {
            if ((endNode != null) && (startNode.ParentNode != endNode.ParentNode))
                throw new ArgumentException("Start and end nodes are expected to have the same parent.");

            StringBuilder builder = new StringBuilder();
            for (Node child = startNode; !child.Equals(endNode); child = child.NextSibling)
                builder.Append(child.GetText());

            return builder.ToString();
        }
 /// <summary>
 /// Goes through siblings starting from the start node until it finds a node of the specified type or null.
 /// </summary>
 private static Node FindNextSibling(Node startNode, NodeType nodeType)
 {
     for (Node node = startNode; node != null; node = node.NextSibling)
     {
         if (node.NodeType.Equals(nodeType))
             return node;
     }
     return null;
 }
        internal Hyperlink(FieldStart fieldStart)
        {
            if (fieldStart == null)
                throw new ArgumentNullException("fieldStart");
            if (!fieldStart.FieldType.Equals(FieldType.FieldHyperlink))
                throw new ArgumentException("Field start type must be FieldHyperlink.");

            mFieldStart = fieldStart;

            // Find the field separator node.
            mFieldSeparator = FindNextSibling(mFieldStart, NodeType.FieldSeparator);
            if (mFieldSeparator == null)
                throw new InvalidOperationException("Cannot find field separator.");

            // Find the field end node. Normally field end will always be found, but in the example document
            // there happens to be a paragraph break included in the hyperlink and this puts the field end
            // in the next paragraph. It will be much more complicated to handle fields which span several
            // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes.
            mFieldEnd = FindNextSibling(mFieldSeparator, NodeType.FieldEnd);

            // Field code looks something like [ HYPERLINK "http:\\www.myurl.com" ], but it can consist of several runs.
            string fieldCode = GetTextSameParent(mFieldStart.NextSibling, mFieldSeparator);
            Match match = gRegex.Match(fieldCode.Trim());
            mIsLocal = (match.Groups[1].Length > 0);	//The link is local if \l is present in the field code.
            mTarget = match.Groups[2].Value;
        }
        internal MergeField(FieldStart fieldStart)
        {
            if (fieldStart.Equals(null))
                throw new ArgumentNullException("fieldStart");
            if (!fieldStart.FieldType.Equals(FieldType.FieldMergeField))
                throw new ArgumentException("Field start type must be FieldMergeField.");

            mFieldStart = fieldStart;

            // Find the field separator node.
            mFieldSeparator = FindNextSibling(mFieldStart, NodeType.FieldSeparator);
            if (mFieldSeparator == null)
                throw new InvalidOperationException("Cannot find field separator.");

            // Find the field end node. Normally field end will always be found, but in the example document
            // there happens to be a paragraph break included in the hyperlink and this puts the field end
            // in the next paragraph. It will be much more complicated to handle fields which span several
            // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes.
            mFieldEnd = FindNextSibling(mFieldSeparator, NodeType.FieldEnd);
        }
예제 #13
0
 public void TestDuplicateRecursive()
 {
     try
     {
         Node child = new Node { Key = 17 };
         Node parent = new Node { Nodes = new[] { child, child, child } };
         child.Nodes = new[] { parent };
         VerifyNodeTree(parent);
         Assert.Fail();
     }
     catch (ProtoException) { }
 }
        //ExStart
        //ExFor:Paragraph.IsEndOfSection
        //ExId:InsertDocumentMain
        //ExSummary:This is a method that inserts contents of one document at a specified location in another document.
        /// <summary>
        /// Inserts content of the external document after the specified node.
        /// Section breaks and section formatting of the inserted document are ignored.
        /// </summary>
        /// <param name="insertAfterNode">Node in the destination document after which the content 
        /// should be inserted. This node should be a block level node (paragraph or table).</param>
        /// <param name="srcDoc">The document to insert.</param>
        static void InsertDocument(Node insertAfterNode, Document srcDoc)
        {
            // Make sure that the node is either a paragraph or table.
            if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) &
              (!insertAfterNode.NodeType.Equals(NodeType.Table)))
                throw new ArgumentException("The destination node should be either a paragraph or table.");

            // We will be inserting into the parent of the destination paragraph.
            CompositeNode dstStory = insertAfterNode.ParentNode;

            // This object will be translating styles and lists during the import.
            NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting);

            // Loop through all sections in the source document.
            foreach (Section srcSection in srcDoc.Sections)
            {
                // Loop through all block level nodes (paragraphs and tables) in the body of the section.
                foreach (Node srcNode in srcSection.Body)
                {
                    // Let's skip the node if it is a last empty paragraph in a section.
                    if (srcNode.NodeType.Equals(NodeType.Paragraph))
                    {
                        Paragraph para = (Paragraph)srcNode;
                        if (para.IsEndOfSection && !para.HasChildNodes)
                            continue;
                    }

                    // This creates a clone of the node, suitable for insertion into the destination document.
                    Node newNode = importer.ImportNode(srcNode, true);

                    // Insert new node after the reference node.
                    dstStory.InsertAfter(newNode, insertAfterNode);
                    insertAfterNode = newNode;
                }
            }
        }