diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddAttributeDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddAttributeDialog.cs index b794b2828c..57ab796f3e 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddAttributeDialog.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddAttributeDialog.cs @@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Gui.XmlForms; namespace ICSharpCode.XmlEditor { - public class AddAttributeDialog : BaseSharpDevelopForm + public class AddAttributeDialog : BaseSharpDevelopForm, IAddAttributeDialog { ListBox attributesListBox; Button okButton; diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddChildTextNodeCommand.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddChildTextNodeCommand.cs new file mode 100644 index 0000000000..a2789476cb --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddChildTextNodeCommand.cs @@ -0,0 +1,26 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Adds a new text node to selected element. + /// + public class AddChildTextNodeCommand : AbstractMenuCommand + { + public override void Run() + { + XmlTreeViewContainerControl view = Owner as XmlTreeViewContainerControl; + if (view != null) { + view.AppendChildTextNode(); + } + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddElementDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddElementDialog.cs index 82c26427a1..ef85a3936a 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddElementDialog.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/AddElementDialog.cs @@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Gui.XmlForms; namespace ICSharpCode.XmlEditor { - public class AddElementDialog : BaseSharpDevelopForm + public class AddElementDialog : BaseSharpDevelopForm, IAddElementDialog { ListBox elementsListBox; Button okButton; diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddAttributeDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddAttributeDialog.cs new file mode 100644 index 0000000000..7f4166fa3d --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddAttributeDialog.cs @@ -0,0 +1,30 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Interface for the AddAttributeDialog. + /// + public interface IAddAttributeDialog : IDisposable + { + /// + /// The attribute names that should be added. These are the + /// attribute names that the user selected in the dialog when + /// it was closed. + /// + string[] AttributeNames {get;} + + /// + /// Shows the dialog. + /// + DialogResult ShowDialog(); + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddElementDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddElementDialog.cs new file mode 100644 index 0000000000..a167e479a2 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IAddElementDialog.cs @@ -0,0 +1,30 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Interface for the AddElementDialog. + /// + public interface IAddElementDialog : IDisposable + { + /// + /// The element names that should be added. These are the + /// element names that the user selected in the dialog when + /// it was closed. + /// + string[] ElementNames {get;} + + /// + /// Shows the dialog. + /// + DialogResult ShowDialog(); + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IXmlTreeView.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IXmlTreeView.cs index 0bbe3cefd9..8d0cf5d45d 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IXmlTreeView.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/IXmlTreeView.cs @@ -104,5 +104,40 @@ namespace ICSharpCode.XmlEditor /// element. /// void InsertElementAfter(XmlElement element); + + /// + /// Removes the specified element from the tree. + /// + void RemoveElement(XmlElement element); + + /// + /// Appends a new child text node to the currently selected + /// element. + /// + void AppendChildTextNode(XmlText textNode); + + /// + /// Inserts a new child text node before the currently + /// selected node. + /// + void InsertTextNodeBefore(XmlText textNode); + + /// + /// Inserts a new child text node after the currently + /// selected node. + /// + void InsertTextNodeAfter(XmlText textNode); + + /// + /// Removes the currently selected text node. + /// + void RemoveTextNode(XmlText textNode); + + /// + /// Informs the xml tree view that the text node + /// has changed and the corresponding tree node + /// needs to be updated. + /// + void UpdateTextNode(XmlText textNode); } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeAfterCommand.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeAfterCommand.cs new file mode 100644 index 0000000000..fe94f3b17d --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeAfterCommand.cs @@ -0,0 +1,27 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Inserts a new text node to after the selected node. + /// + public class InsertTextNodeAfterCommand : AbstractMenuCommand + { + public override void Run() + { + XmlTreeViewContainerControl view = Owner as XmlTreeViewContainerControl; + if (view != null) { + view.InsertTextNodeAfter(); + } + } + } +} + diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeBeforeCommand.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeBeforeCommand.cs new file mode 100644 index 0000000000..d9214f8ded --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/InsertTextNodeBeforeCommand.cs @@ -0,0 +1,27 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Inserts a new text node to before the selected node. + /// + public class InsertTextNodeBeforeCommand : AbstractMenuCommand + { + public override void Run() + { + XmlTreeViewContainerControl view = Owner as XmlTreeViewContainerControl; + if (view != null) { + view.InsertTextNodeBefore(); + } + } + } +} + diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveElementCommand.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveElementCommand.cs new file mode 100644 index 0000000000..456420bb8a --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveElementCommand.cs @@ -0,0 +1,26 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Removes the selected element from the XML tree. + /// + public class RemoveElementCommand : AbstractMenuCommand + { + public override void Run() + { + XmlTreeViewContainerControl view = Owner as XmlTreeViewContainerControl; + if (view != null) { + view.RemoveElement(); + } + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveTextNodeCommand.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveTextNodeCommand.cs new file mode 100644 index 0000000000..de441eedbd --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/RemoveTextNodeCommand.cs @@ -0,0 +1,26 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.XmlEditor +{ + /// + /// Removes the currently selected text node from the XML tree. + /// + public class RemoveTextNodeCommand : AbstractMenuCommand + { + public override void Run() + { + XmlTreeViewContainerControl view = Owner as XmlTreeViewContainerControl; + if (view != null) { + view.RemoveTextNode(); + } + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTextTreeNode.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTextTreeNode.cs index 277c52d41b..49e96fff06 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTextTreeNode.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTextTreeNode.cs @@ -22,7 +22,7 @@ namespace ICSharpCode.XmlEditor this.xmlText = xmlText; ImageKey = XmlTextTreeNodeImageKey; SelectedImageKey = ImageKey; - Text = GetDisplayText(xmlText.InnerText); + Update(); } public XmlText XmlText { @@ -31,6 +31,15 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Updates the display text based on changes in the + /// XmlText associated with this node. + /// + public void Update() + { + Text = GetDisplayText(xmlText.InnerText); + } + /// /// Gets the text to display for this tree node. /// diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeEditor.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeEditor.cs index 3d1ca46075..2d97dd1a59 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeEditor.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeEditor.cs @@ -131,6 +131,7 @@ namespace ICSharpCode.XmlEditor if (textNode != null) { view.IsDirty = true; textNode.Value = view.TextContent; + view.UpdateTextNode(textNode); } } @@ -200,6 +201,94 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Removes the currently selected element. + /// + public void RemoveElement() + { + XmlElement selectedElement = view.SelectedElement; + if (selectedElement != null) { + XmlNode parentNode = selectedElement.ParentNode; + parentNode.RemoveChild(selectedElement); + view.IsDirty = true; + view.RemoveElement(selectedElement); + } + } + + /// + /// Removes the currently select text node. + /// + public void RemoveTextNode() + { + XmlText textNode = view.SelectedTextNode; + if (textNode != null) { + XmlNode parentNode = textNode.ParentNode; + parentNode.RemoveChild(textNode); + view.IsDirty = true; + view.RemoveTextNode(textNode); + } + } + + /// + /// Adds a child text node to the current selected element. + /// + public void AddChildTextNode() + { + XmlElement selectedElement = view.SelectedElement; + if (selectedElement != null) { + XmlText textNode = document.CreateTextNode(String.Empty); + selectedElement.AppendChild(textNode); + view.IsDirty = true; + view.AppendChildTextNode(textNode); + } + } + + /// + /// Inserts a text node before the currently selected node. + /// + public void InsertTextNodeBefore() + { + // Get the currently selected text node or element. + XmlNode selectedNode = view.SelectedTextNode; + if (selectedNode == null) { + selectedNode = view.SelectedElement; + } + + // Insert the text node before the selected node. + if (selectedNode != null) { + XmlElement parentElement = selectedNode.ParentNode as XmlElement; + if (parentElement != null) { + XmlText textNode = document.CreateTextNode(String.Empty); + parentElement.InsertBefore(textNode, selectedNode); + view.IsDirty = true; + view.InsertTextNodeBefore(textNode); + } + } + } + + /// + /// Inserts a text node after the currently selected node. + /// + public void InsertTextNodeAfter() + { + // Get the currently selected text node or element. + XmlNode selectedNode = view.SelectedTextNode; + if (selectedNode == null) { + selectedNode = view.SelectedElement; + } + + // Insert the text node after the selected node. + if (selectedNode != null) { + XmlElement parentElement = selectedNode.ParentNode as XmlElement; + if (parentElement != null) { + XmlText textNode = document.CreateTextNode(String.Empty); + parentElement.InsertAfter(textNode, selectedNode); + view.IsDirty = true; + view.InsertTextNodeAfter(textNode); + } + } + } + /// /// Gets the missing attributes for the specified element based /// on its associated schema. diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewContainerControl.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewContainerControl.cs index c33957c313..ae0939663e 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewContainerControl.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewContainerControl.cs @@ -33,7 +33,8 @@ namespace ICSharpCode.XmlEditor Nothing = 0, ElementSelected = 1, RootElementSelected = 2, - AttributeSelected = 4 + AttributeSelected = 4, + TextNodeSelected = 8 } public event EventHandler DirtyChanged; @@ -44,6 +45,9 @@ namespace ICSharpCode.XmlEditor InitImages(); } + /// + /// Gets the current XmlTreeViewContainerControlState. + /// public Enum InternalState { get { XmlTreeViewContainerControlState state = XmlTreeViewContainerControlState.Nothing; @@ -56,6 +60,9 @@ namespace ICSharpCode.XmlEditor if (SelectedAttribute != null) { state |= XmlTreeViewContainerControlState.AttributeSelected; } + if (SelectedTextNode != null) { + state = XmlTreeViewContainerControlState.TextNodeSelected; + } return state; } } @@ -248,7 +255,7 @@ namespace ICSharpCode.XmlEditor /// The attributes selected by the user. public string[] SelectNewAttributes(string[] attributes) { - using (AddAttributeDialog addAttributeDialog = new AddAttributeDialog(attributes)) { + using (IAddAttributeDialog addAttributeDialog = CreateAddAttributeDialog(attributes)) { if (addAttributeDialog.ShowDialog() == DialogResult.OK) { return addAttributeDialog.AttributeNames; } @@ -273,7 +280,7 @@ namespace ICSharpCode.XmlEditor /// The elements selected by the user. public string[] SelectNewElements(string[] elements) { - using (AddElementDialog addElementDialog = new AddElementDialog(elements)) { + using (IAddElementDialog addElementDialog = CreateAddElementDialog(elements)) { if (addElementDialog.ShowDialog() == DialogResult.OK) { return addElementDialog.ElementNames; } @@ -331,6 +338,100 @@ namespace ICSharpCode.XmlEditor xmlElementTreeView.InsertElementAfter(element); } + /// + /// Removes the selected element. + /// + public void RemoveElement() + { + editor.RemoveElement(); + } + + /// + /// Removes the specified element from the tree. + /// + public void RemoveElement(XmlElement element) + { + xmlElementTreeView.RemoveElement(element); + } + + /// + /// Appends a new text node to the currently selected + /// element. + /// + public void AppendChildTextNode(XmlText textNode) + { + xmlElementTreeView.AppendChildTextNode(textNode); + } + + /// + /// Appends a new text node to the currently selected + /// element. + /// + public void AppendChildTextNode() + { + editor.AddChildTextNode(); + } + + /// + /// Inserts a new text node before the currently selected + /// node. + /// + public void InsertTextNodeBefore() + { + editor.InsertTextNodeBefore(); + } + + /// + /// Inserts a new text node before the currently selected + /// node. + /// + public void InsertTextNodeBefore(XmlText textNode) + { + xmlElementTreeView.InsertTextNodeBefore(textNode); + } + + /// + /// Inserts a new text node after the currently selected + /// node. + /// + public void InsertTextNodeAfter() + { + editor.InsertTextNodeAfter(); + } + + /// + /// Inserts a new text node after the currently selected + /// node. + /// + public void InsertTextNodeAfter(XmlText textNode) + { + xmlElementTreeView.InsertTextNodeAfter(textNode); + } + + /// + /// Removes the currently selected text node. + /// + public void RemoveTextNode() + { + editor.RemoveTextNode(); + } + + /// + /// Removes the currently selected text node. + /// + public void RemoveTextNode(XmlText textNode) + { + xmlElementTreeView.RemoveTextNode(textNode); + } + + /// + /// Updates the corresponding tree node's text. + /// + public void UpdateTextNode(XmlText textNode) + { + xmlElementTreeView.UpdateTextNode(textNode); + } + /// /// Disposes resources used by the control. /// @@ -345,6 +446,26 @@ namespace ICSharpCode.XmlEditor base.Dispose(disposing); } + /// + /// Creates a new AddElementDialog. + /// + /// The element names to be listed in the + /// dialog. + protected virtual IAddElementDialog CreateAddElementDialog(string[] elementNames) + { + return new AddElementDialog(elementNames); + } + + /// + /// Creates a new AddAttributeDialog. + /// + /// The attribute names to be listed in the + /// dialog. + protected virtual IAddAttributeDialog CreateAddAttributeDialog(string[] attributeNames) + { + return new AddAttributeDialog(attributeNames); + } + #region Forms Designer generated code /// @@ -462,22 +583,22 @@ namespace ICSharpCode.XmlEditor #endregion /// - /// Creates an image list that will be used for the XmlTreeViewControl. + /// This method is protected only so we can easily test + /// what happens when this method is called. Triggering + /// a TextChanged event is difficult to do from unit tests. + /// You can trigger it it by setting the textBox's Rtf property. /// - void InitImages() + protected void TextBoxTextChanged(object sender, EventArgs e) { - if (components == null) { - components = new Container(); - } - ImageList images = new ImageList(components); - Image xmlElementImage = Image.FromStream(GetType().Assembly.GetManifestResourceStream("ICSharpCode.XmlEditor.Resources.XmlElementTreeNodeIcon.png")); - images.Images.Add(XmlElementTreeNode.XmlElementTreeNodeImageKey, xmlElementImage); - Image xmlTextImage = Image.FromStream(GetType().Assembly.GetManifestResourceStream("ICSharpCode.XmlEditor.Resources.XmlTextTreeNodeIcon.png")); - images.Images.Add(XmlTextTreeNode.XmlTextTreeNodeImageKey, xmlTextImage); - xmlElementTreeView.ImageList = images; + bool previousIsDirty = dirty; + editor.TextContentChanged(); + OnXmlChanged(previousIsDirty); } - void XmlElementTreeViewAfterSelect(object sender, TreeViewEventArgs e) + /// + /// This method is protected so we can test it. + /// + protected void XmlElementTreeViewAfterSelect(object sender, TreeViewEventArgs e) { if (xmlElementTreeView.IsTextNodeSelected) { editor.SelectedTextNodeChanged(); @@ -486,20 +607,34 @@ namespace ICSharpCode.XmlEditor } } - void TextBoxTextChanged(object sender, EventArgs e) + /// + /// This method is protected so we can test it. + /// + protected void AttributesGridPropertyValueChanged(object s, PropertyValueChangedEventArgs e) { bool previousIsDirty = dirty; - editor.TextContentChanged(); + editor.AttributeValueChanged(); OnXmlChanged(previousIsDirty); } - - void AttributesGridPropertyValueChanged(object s, PropertyValueChangedEventArgs e) + + /// + /// Creates an image list that will be used for the XmlTreeViewControl. + /// + void InitImages() { - bool previousIsDirty = dirty; - editor.AttributeValueChanged(); - OnXmlChanged(previousIsDirty); + if (components == null) { + components = new Container(); + } + ImageList images = new ImageList(components); + Image xmlElementImage = Image.FromStream(typeof(XmlTreeViewContainerControl).Assembly.GetManifestResourceStream("ICSharpCode.XmlEditor.Resources.XmlElementTreeNodeIcon.png")); + images.Images.Add(XmlElementTreeNode.XmlElementTreeNodeImageKey, xmlElementImage); + Image xmlTextImage = Image.FromStream(typeof(XmlTreeViewContainerControl).Assembly.GetManifestResourceStream("ICSharpCode.XmlEditor.Resources.XmlTextTreeNodeIcon.png")); + images.Images.Add(XmlTextTreeNode.XmlTextTreeNodeImageKey, xmlTextImage); + xmlElementTreeView.ImageList = images; } + + /// /// Raises the dirty changed event if the dirty flag has changed. /// @@ -545,9 +680,6 @@ namespace ICSharpCode.XmlEditor /// Gets or sets whether the text node text box is visible. /// bool IsTextBoxVisible { - get { - return textBoxVisible; - } set { textBoxVisible = value; if (value) { diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewControl.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewControl.cs index 07a3603482..9c91da2798 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewControl.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlTreeViewControl.cs @@ -35,6 +35,9 @@ namespace ICSharpCode.XmlEditor { } + /// + /// Gets or sets the root element currently being displayed. + /// [Browsable(false)] public XmlElement DocumentElement { get { @@ -53,6 +56,9 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Gets the selected element in the tree. + /// public XmlElement SelectedElement { get { XmlElementTreeNode xmlElementTreeNode = SelectedElementNode; @@ -63,12 +69,18 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Determines whether an element is selected in the tree. + /// public bool IsElementSelected { get { return SelectedElement != null; } } + /// + /// Gets the selected text node in the tree. + /// public XmlText SelectedTextNode { get { XmlTextTreeNode xmlTextTreeNode = SelectedNode as XmlTextTreeNode; @@ -80,6 +92,9 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Determines whether a text node is selected in the tree. + /// public bool IsTextNodeSelected { get { return SelectedTextNode != null; @@ -115,6 +130,19 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Appends a new child text node to the currently selected element. + /// + public void AppendChildTextNode(XmlText textNode) + { + XmlElementTreeNode selectedNode = SelectedElementNode; + if (selectedNode != null) { + XmlTextTreeNode newNode = new XmlTextTreeNode(textNode); + newNode.AddTo(selectedNode); + selectedNode.Expand(); + } + } + /// /// Inserts a new element node before the currently selected /// node. @@ -133,6 +161,80 @@ namespace ICSharpCode.XmlEditor InsertElement(element, InsertionMode.After); } + /// + /// Removes the specified element from the tree. + /// + public void RemoveElement(XmlElement element) + { + XmlElementTreeNode selectedElementTreeNode = SelectedNode as XmlElementTreeNode; + if (selectedElementTreeNode != null && selectedElementTreeNode.XmlElement == element) { + // Remove selected tree node. + selectedElementTreeNode.Remove(); + } else { + XmlElementTreeNode elementTreeNode = FindElementNode(element, Nodes); + if (elementTreeNode != null) { + elementTreeNode.Remove(); + } + } + } + + /// + /// Removes the specified text node from the tree. + /// + public void RemoveTextNode(XmlText textNode) + { + XmlTextTreeNode selectedTextTreeNode = SelectedNode as XmlTextTreeNode; + if (selectedTextTreeNode != null && selectedTextTreeNode.XmlText == textNode) { + selectedTextTreeNode.Remove(); + } else { + XmlTextTreeNode textTreeNode = FindTextNode(textNode, Nodes); + if (textTreeNode != null) { + textTreeNode.Remove(); + } + } + } + + /// + /// Inserts a text node before the currently selected + /// node. + /// + public void InsertTextNodeBefore(XmlText textNode) + { + InsertTextNode(textNode, InsertionMode.Before); + } + + /// + /// Inserts a text node after the currently selected + /// node. + /// + public void InsertTextNodeAfter(XmlText textNode) + { + InsertTextNode(textNode, InsertionMode.After); + } + + /// + /// Updates the corresponding tree node's text based on + /// the textNode's value. + /// + public void UpdateTextNode(XmlText textNode) + { + XmlTextTreeNode selectedTextTreeNode = SelectedNode as XmlTextTreeNode; + if (selectedTextTreeNode != null && selectedTextTreeNode.XmlText == textNode) { + selectedTextTreeNode.Update(); + } else { + XmlTextTreeNode textTreeNode = FindTextNode(textNode, Nodes); + if (textTreeNode != null) { + textTreeNode.Update(); + } + } + } + + /// + /// If no node is selected after a mouse click then we make + /// sure the AfterSelect event is fired. Standard behaviour is + /// for the AfterSelect event not to be fired when the user + /// deselects all tree nodes. + /// protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); @@ -141,6 +243,9 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Displays the document in the xml tree. + /// void ShowDocumentElement() { Nodes.Clear(); @@ -150,6 +255,9 @@ namespace ICSharpCode.XmlEditor } } + /// + /// Returns the selected xml element tree node. + /// XmlElementTreeNode SelectedElementNode { get { return SelectedNode as XmlElementTreeNode; @@ -173,5 +281,69 @@ namespace ICSharpCode.XmlEditor newNode.Insert(index, parentNode); } } + + /// + /// Inserts a new text node either before or after the + /// currently selected node. + /// + void InsertTextNode(XmlText textNode, InsertionMode insertionMode) + { + ExtTreeNode selectedNode = (ExtTreeNode)SelectedNode; + if (selectedNode != null) { + XmlElementTreeNode parentNode = (XmlElementTreeNode)selectedNode.Parent; + XmlTextTreeNode newNode = new XmlTextTreeNode(textNode); + int index = parentNode.Nodes.IndexOf(selectedNode); + if (insertionMode == InsertionMode.After) { + index++; + } + newNode.Insert(index, parentNode); + } + } + + /// + /// Looks at all the nodes in the tree view and returns the + /// tree node that represents the specified element. + /// + XmlElementTreeNode FindElementNode(XmlElement element, TreeNodeCollection nodes) + { + foreach (ExtTreeNode node in nodes) { + XmlElementTreeNode elementTreeNode = node as XmlElementTreeNode; + if (elementTreeNode != null) { + if (elementTreeNode.XmlElement == element) { + return elementTreeNode; + } + + // Look for a match in the element's child nodes. + XmlElementTreeNode childElementTreeNode = FindElementNode(element, elementTreeNode.Nodes); + if (childElementTreeNode != null) { + return childElementTreeNode; + } + } + } + return null; + } + + /// + /// Looks at all the nodes in the tree view and returns the + /// tree node that represents the specified text node. + /// + XmlTextTreeNode FindTextNode(XmlText textNode, TreeNodeCollection nodes) + { + foreach (ExtTreeNode node in nodes) { + XmlTextTreeNode textTreeNode = node as XmlTextTreeNode; + if (textTreeNode != null) { + if (textTreeNode.XmlText == textNode) { + return textTreeNode; + } + } else { + // Look for a match in the node's child nodes. + XmlTextTreeNode childTextTreeNode = FindTextNode(textNode, node.Nodes); + if (childTextTreeNode != null) { + return childTextTreeNode; + } + } + } + return null; + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin index 416fb83896..4e3c8c9f05 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin @@ -211,11 +211,48 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj index 716b7d219c..e9c52a4190 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj +++ b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.csproj @@ -54,6 +54,13 @@ + + + + + + + UserControl diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/QualifiedNameTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/QualifiedNameTestFixture.cs index eabfedb5c6..b084d0e7e0 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/QualifiedNameTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Parser/QualifiedNameTestFixture.cs @@ -8,6 +8,7 @@ using ICSharpCode.XmlEditor; using NUnit.Framework; using System; +using System.Xml; namespace XmlEditor.Tests.Parser { @@ -60,6 +61,15 @@ namespace XmlEditor.Tests.Parser QualifiedName name2 = null; Assert.IsFalse(name1 == name2, "Should not be the same."); - } + } + + [Test] + public void HashCodeTest() + { + QualifiedName name1 = new QualifiedName("foo", "http://foo.com", "f"); + XmlQualifiedName xmlQualifiedName = new XmlQualifiedName("foo", "http://foo.com"); + + Assert.AreEqual(name1.GetHashCode(), xmlQualifiedName.GetHashCode()); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Paths/NoElementPathTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Paths/NoElementPathTestFixture.cs index a3e6d5bfc0..aed5cabb73 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Paths/NoElementPathTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Paths/NoElementPathTestFixture.cs @@ -37,6 +37,12 @@ namespace XmlEditor.Tests.Paths Assert.IsTrue(newPath.Equals(path), "Should be equal."); } + [Test] + public void EqualsItself() + { + Assert.IsTrue(path.Equals(path), "Should be equal."); + } + [Test] public void NotEqual() { @@ -44,7 +50,14 @@ namespace XmlEditor.Tests.Paths newPath.Elements.Add(new QualifiedName("Foo", "bar")); Assert.IsFalse(newPath.Equals(path), "Should not be equal."); - } + } + + [Test] + public void NotEqualToADifferentType() + { + Object o = new Object(); + Assert.IsFalse(path.Equals(o), "Should not be equal."); + } [Test] public void Compact() @@ -52,5 +65,11 @@ namespace XmlEditor.Tests.Paths path.Compact(); Equality(); } + + [Test] + public void HashCode() + { + Assert.AreEqual(path.Elements.GetHashCode(), path.GetHashCode()); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddChildTextNodeTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddChildTextNodeTestFixture.cs new file mode 100644 index 0000000000..942e01bf2a --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddChildTextNodeTestFixture.cs @@ -0,0 +1,91 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using System; +using System.IO; +using System.Xml; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Checks that a text node is added by the XmlTreeEditor as + /// a child of the selected element. + /// + [TestFixture] + public class AddChildTextNodeTestFixture : XmlTreeViewTestFixtureBase + { + XmlElement paragraphElement; + + [SetUp] + public void Init() + { + base.InitFixture(); + paragraphElement = (XmlElement)editor.Document.SelectSingleNode("/html/body/p"); + mockXmlTreeView.SelectedElement = paragraphElement; + editor.AddChildTextNode(); + } + + [Test] + public void ParagraphElementHasChildNodes() + { + Assert.AreEqual(1, paragraphElement.ChildNodes.Count); + } + + [Test] + public void NewTextNodeAdded() + { + XmlNode node = paragraphElement.FirstChild; + Assert.IsInstanceOfType(typeof(XmlText), node); + } + + [Test] + public void IsDirty() + { + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + [Test] + public void AddChildTextNodeWhenNoElementSelected() + { + mockXmlTreeView.SelectedElement = null; + mockXmlTreeView.IsDirty = false; + editor.AddChildTextNode(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + [Test] + public void TextNodeAddedToView() + { + Assert.AreEqual(1, mockXmlTreeView.ChildTextNodesAdded.Count); + } + + /// + /// Returns the xhtml strict schema as the default schema. + /// + protected override XmlSchemaCompletionData DefaultSchemaCompletionData { + get { + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + return new XmlSchemaCompletionData(reader); + } + } + + protected override string GetXml() + { + return "\r\n" + + "\t\r\n" + + "\t\t\r\n" + + "\t\r\n" + + "\t\r\n" + + "\t\t

\r\n" + + "\t\r\n" + + ""; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddElementsToTreeControlTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddElementsToTreeControlTestFixture.cs index c3d198c30c..402a9ecf95 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddElementsToTreeControlTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/AddElementsToTreeControlTestFixture.cs @@ -23,40 +23,44 @@ namespace XmlEditor.Tests.Tree [SetUp] public void SetUpFixture() { - doc = new XmlDocument(); - doc.LoadXml(""); - using (XmlTreeViewControl treeView = new XmlTreeViewControl()) { - treeView.DocumentElement = doc.DocumentElement; + using (XmlTreeViewContainerControl treeViewContainer = new XmlTreeViewContainerControl()) { + XmlCompletionDataProvider completionDataProvider = new XmlCompletionDataProvider(new XmlSchemaCompletionDataCollection(), null, String.Empty); + treeViewContainer.LoadXml("", completionDataProvider); + + doc = treeViewContainer.Document; + XmlTreeViewControl treeView = treeViewContainer.TreeView; + + //treeView.DocumentElement = doc.DocumentElement; rootNode = (XmlElementTreeNode)treeView.Nodes[0]; // No node selected in treeview - adding a child // node should do nothing. treeView.SelectedNode = null; XmlElement testElement = doc.CreateElement("test"); - treeView.AppendChildElement(testElement); + treeViewContainer.AppendChildElement(testElement); treeView.SelectedNode = rootNode; XmlElement childElement = doc.CreateElement("child"); - treeView.AppendChildElement(childElement); + treeViewContainer.AppendChildElement(childElement); // No node selected in treeview - inserting a node // node should do nothing. treeView.SelectedNode = null; - treeView.AppendChildElement(testElement); + treeViewContainer.AppendChildElement(testElement); XmlElementTreeNode childNode = (XmlElementTreeNode)rootNode.Nodes[0]; treeView.SelectedNode = childNode; XmlElement beforeElement = doc.CreateElement("before"); - treeView.InsertElementBefore(beforeElement); + treeViewContainer.InsertElementBefore(beforeElement); // No node selected in treeview - inserting a node // node should do nothing. treeView.SelectedNode = null; - treeView.AppendChildElement(testElement); + treeViewContainer.AppendChildElement(testElement); treeView.SelectedNode = childNode; XmlElement afterElement = doc.CreateElement("after"); - treeView.InsertElementAfter(afterElement); + treeViewContainer.InsertElementAfter(afterElement); } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/GetXmlAttributePropertyDescriptorTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/GetXmlAttributePropertyDescriptorTestFixture.cs index 7d67a4d903..11d1c1fd8d 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/GetXmlAttributePropertyDescriptorTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/GetXmlAttributePropertyDescriptorTestFixture.cs @@ -93,5 +93,13 @@ namespace XmlEditor.Tests.Tree Assert.AreEqual("new value", (String)firstAttributePropertyDescriptor.GetValue(null)); Assert.AreEqual("new value", firstAttribute.Value); } + + [Test] + public void ResetValueDoesNothing() + { + firstAttributePropertyDescriptor.SetValue(null, "new value"); + firstAttributePropertyDescriptor.ResetValue(null); + Assert.AreEqual("new value", firstAttribute.Value); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeAfterTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeAfterTestFixture.cs new file mode 100644 index 0000000000..d63a9c8f79 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeAfterTestFixture.cs @@ -0,0 +1,133 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + ///

+ /// Tests that a text node is inserted after the selected node + /// by the XmlTreeEditor. + /// + [TestFixture] + public class InsertTextNodeAfterTestFixture : XmlTreeViewTestFixtureBase + { + XmlElement paragraphElement; + XmlText textNode; + + [SetUp] + public void Init() + { + base.InitFixture(); + paragraphElement = (XmlElement)editor.Document.SelectSingleNode("/html/body/p"); + textNode = (XmlText)paragraphElement.SelectSingleNode("text()"); + mockXmlTreeView.SelectedTextNode = textNode; + + editor.InsertTextNodeAfter(); + } + + [Test] + public void IsDirty() + { + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + [Test] + public void ParagraphNodeHasTwoChildNodes() + { + Assert.AreEqual(2, paragraphElement.ChildNodes.Count); + } + + [Test] + public void TextNodeInserted() + { + XmlText lastTextNode = (XmlText)paragraphElement.LastChild; + Assert.AreEqual(String.Empty, lastTextNode.Value); + } + + /// + /// Makes sure that nothing happens if we try to insert a + /// text node when a text node is not already selected. + /// + [Test] + public void NoNodeSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeAfter(); + ParagraphNodeHasTwoChildNodes(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + [Test] + public void TextNodeAddedToView() + { + Assert.AreEqual(1, mockXmlTreeView.TextNodesInsertedAfter.Count); + } + + /// + /// Tests that we can insert a text node after the + /// an element if it is not the root element. + /// + [Test] + public void ElementSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.SelectedElement = paragraphElement; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeAfter(); + + XmlElement bodyElement = (XmlElement)paragraphElement.ParentNode; + Assert.AreEqual(2, bodyElement.ChildNodes.Count); + Assert.IsInstanceOfType(typeof(XmlText), bodyElement.LastChild); + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + /// + /// Tests that we cannot insert a text node after the + /// root element. + /// + [Test] + public void RootElementSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.SelectedElement = editor.Document.DocumentElement; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeAfter(); + ParagraphNodeHasTwoChildNodes(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + /// + /// Returns the xhtml strict schema as the default schema. + /// + protected override XmlSchemaCompletionData DefaultSchemaCompletionData { + get { + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + return new XmlSchemaCompletionData(reader); + } + } + + protected override string GetXml() + { + return "\r\n" + + "\t\r\n" + + "\t\t\r\n" + + "\t\r\n" + + "\t\r\n" + + "\t\t

text

\r\n" + + "\t\r\n" + + ""; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeBeforeTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeBeforeTestFixture.cs new file mode 100644 index 0000000000..578baeeeaf --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/InsertTextNodeBeforeTestFixture.cs @@ -0,0 +1,133 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests that a text node is inserted before the selected node + /// by the XmlTreeEditor. + /// + [TestFixture] + public class InsertTextNodeBeforeTestFixture : XmlTreeViewTestFixtureBase + { + XmlElement paragraphElement; + XmlText textNode; + + [SetUp] + public void Init() + { + base.InitFixture(); + paragraphElement = (XmlElement)editor.Document.SelectSingleNode("/html/body/p"); + textNode = (XmlText)paragraphElement.SelectSingleNode("text()"); + mockXmlTreeView.SelectedTextNode = textNode; + + editor.InsertTextNodeBefore(); + } + + [Test] + public void IsDirty() + { + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + [Test] + public void ParagraphNodeHasTwoChildNodes() + { + Assert.AreEqual(2, paragraphElement.ChildNodes.Count); + } + + [Test] + public void TextNodeInserted() + { + XmlText firstTextNode = (XmlText)paragraphElement.ChildNodes[0]; + Assert.AreEqual(String.Empty, firstTextNode.Value); + } + + /// + /// Makes sure that nothing happens if we try to insert a + /// text node when a text node is not already selected. + /// + [Test] + public void NoNodeSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeBefore(); + ParagraphNodeHasTwoChildNodes(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + [Test] + public void TextNodeAddedToView() + { + Assert.AreEqual(1, mockXmlTreeView.TextNodesInsertedBefore.Count); + } + + /// + /// Tests that we can insert a text node before the + /// an element if it is not the root element. + /// + [Test] + public void ElementSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.SelectedElement = paragraphElement; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeBefore(); + + XmlElement bodyElement = (XmlElement)paragraphElement.ParentNode; + Assert.AreEqual(2, bodyElement.ChildNodes.Count); + Assert.IsInstanceOfType(typeof(XmlText), bodyElement.FirstChild); + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + /// + /// Tests that we cannot insert a text node before the + /// root element. + /// + [Test] + public void RootElementSelected() + { + mockXmlTreeView.SelectedTextNode = null; + mockXmlTreeView.SelectedElement = editor.Document.DocumentElement; + mockXmlTreeView.IsDirty = false; + editor.InsertTextNodeBefore(); + ParagraphNodeHasTwoChildNodes(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + /// + /// Returns the xhtml strict schema as the default schema. + /// + protected override XmlSchemaCompletionData DefaultSchemaCompletionData { + get { + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + return new XmlSchemaCompletionData(reader); + } + } + + protected override string GetXml() + { + return "\r\n" + + "\t\r\n" + + "\t\t\r\n" + + "\t\r\n" + + "\t\r\n" + + "\t\t

text

\r\n" + + "\t\r\n" + + ""; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MenuCommandsTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MenuCommandsTestFixture.cs new file mode 100644 index 0000000000..da50efa257 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MenuCommandsTestFixture.cs @@ -0,0 +1,400 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Windows.Forms; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests the various menu commands that can be used on the + /// Xml Tree (e.g. InsertElementBeforeCommand). + /// + [TestFixture] + public class MenuCommandsTestFixture + { + DerivedXmlTreeViewContainerControl treeViewContainer; + XmlDocument doc; + XmlTreeViewControl treeView; + XmlElement bodyElement; + XmlElementTreeNode htmlTreeNode; + XmlElementTreeNode bodyTreeNode; + + [SetUp] + public void Init() + { + treeViewContainer = new DerivedXmlTreeViewContainerControl(); + + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + XmlSchemaCompletionData xhtmlSchema = new XmlSchemaCompletionData(reader); + XmlSchemaCompletionDataCollection schemas = new XmlSchemaCompletionDataCollection(); + XmlCompletionDataProvider provider = new XmlCompletionDataProvider(schemas, xhtmlSchema, String.Empty); + + treeViewContainer.LoadXml("", provider); + doc = treeViewContainer.Document; + treeView = treeViewContainer.TreeView; + + htmlTreeNode = (XmlElementTreeNode)treeView.Nodes[0]; + htmlTreeNode.Expanding(); + bodyTreeNode = (XmlElementTreeNode)htmlTreeNode.Nodes[0]; + + bodyElement = (XmlElement)doc.SelectSingleNode("/html/body"); + } + + [TearDown] + public void TearDown() + { + if (treeViewContainer != null) { + treeViewContainer.Dispose(); + } + } + + /// + /// Nothing should happen if the owner is the XmlTreeViewContainerControl. + /// + [Test] + public void InsertElementBeforeWithUnknownOwner() + { + InsertElementBeforeCommand command = new InsertElementBeforeCommand(); + command.Owner = this; + command.Run(); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void InsertElementBeforeWithNullOwner() + { + InsertElementBeforeCommand command = new InsertElementBeforeCommand(); + command.Run(); + } + + /// + /// Here we produce dummy data from our mock AddElementDialog + /// and check that the InsertElementBeforeCommand inserts + /// the correct element + /// + [Test] + public void InsertElementBefore() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddElementDialogElementNamesReturned.Add("head"); + InsertElementBeforeCommand command = new InsertElementBeforeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlElement headElement = (XmlElement)doc.SelectSingleNode("/html/head"); + Assert.IsNotNull(headElement, "Expected a new head element to be inserted."); + Assert.AreSame(headElement, doc.DocumentElement.FirstChild); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void InsertElementAfterWithNullOwner() + { + InsertElementAfterCommand command = new InsertElementAfterCommand(); + command.Run(); + } + + [Test] + public void InsertElementAfter() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddElementDialogElementNamesReturned.Add("afterBody"); + InsertElementAfterCommand command = new InsertElementAfterCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlElement newElement = (XmlElement)doc.SelectSingleNode("/html/afterBody"); + Assert.IsNotNull(newElement, "Expected a new element to be inserted."); + Assert.AreSame(newElement, doc.DocumentElement.ChildNodes[1]); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void AddChildElementWithNullOwner() + { + AddChildElementCommand command = new AddChildElementCommand(); + command.Run(); + } + + [Test] + public void AddChildElement() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddElementDialogElementNamesReturned.Add("p"); + AddChildElementCommand command = new AddChildElementCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlElement paragraphElement = (XmlElement)bodyElement.SelectSingleNode("p"); + Assert.IsNotNull(paragraphElement, "Expected a new

element to be appended."); + } + + ///

+ /// Tests the XmlTreeViewContainer.SelectNewElements methods + /// returns an empty string array when the AddElementDialog + /// is cancelled. + /// + [Test] + public void AddElementDialogCancelled() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddElementDialogElementNamesReturned.Add("p"); + treeViewContainer.AddElementDialogResult = DialogResult.Cancel; + + string[] elements = treeViewContainer.SelectNewElements(new string[] {"a"}); + Assert.AreEqual(0, elements.Length); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void AddAttributeWithNullOwner() + { + AddAttributeCommand command = new AddAttributeCommand(); + command.Run(); + } + + [Test] + public void AddAttribute() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddAttributeDialogAttributeNamesReturned.Add("class"); + AddAttributeCommand command = new AddAttributeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + Assert.IsTrue(bodyElement.HasAttribute("class")); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void RemoveAttributeWithNullOwner() + { + RemoveAttributeCommand command = new RemoveAttributeCommand(); + command.Run(); + } + + [Test] + public void RemoveAttribute() + { + AddAttribute(); + + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.ShowAttributes(treeView.SelectedElement.Attributes); + + Assert.IsNotNull(treeViewContainer.AttributesGrid.SelectedGridItem, + "Sanity check - should have a grid item selected."); + + RemoveAttributeCommand command = new RemoveAttributeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + Assert.IsFalse(bodyElement.HasAttribute("class")); + } + + /// + /// Tests the XmlTreeViewContainer.SelectNewAttributes methods + /// returns an empty string array when the AddAttributeDialog + /// is cancelled. + /// + [Test] + public void AddAttributeDialogCancelled() + { + treeView.SelectedNode = bodyTreeNode; + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.AddAttributeDialogAttributeNamesReturned.Add("class"); + treeViewContainer.AddAttributeDialogResult = DialogResult.Cancel; + AddAttributeCommand command = new AddAttributeCommand(); + + string[] attributes = treeViewContainer.SelectNewAttributes(new string[] {"a"}); + Assert.AreEqual(0, attributes.Length); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void AddChildTextNodeWithNullOwner() + { + AddChildTextNodeCommand command = new AddChildTextNodeCommand(); + command.Run(); + } + + [Test] + public void AddChildTextNode() + { + treeView.SelectedNode = bodyTreeNode; + AddChildTextNodeCommand command = new AddChildTextNodeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlText textNode = bodyElement.SelectSingleNode("text()") as XmlText; + Assert.IsNotNull(textNode, "Expected a new text node element to be appended."); + + XmlTextTreeNode textTreeNode = bodyTreeNode.Nodes[0] as XmlTextTreeNode; + Assert.IsNotNull(textTreeNode); + } + + /// + /// Makes sure that nothing happens if we try to add a text + /// node to the currently selected element node when there + /// is no selected element node. + /// + [Test] + public void AddChildTextNodeWhenNoElementSelected() + { + treeView.SelectedNode = null; + XmlText newTextNode = doc.CreateTextNode(String.Empty); + treeView.AppendChildTextNode(newTextNode); + + XmlText textNode = bodyElement.SelectSingleNode("text()") as XmlText; + Assert.IsNull(textNode); + } + + /// + /// Nothing should happen if the owner is null. + /// + [Test] + public void InsertTextNodeBeforeWithNullOwner() + { + InsertTextNodeBeforeCommand command = new InsertTextNodeBeforeCommand(); + command.Run(); + } + + [Test] + public void InsertTextNodeBefore() + { + AddChildTextNode(); + + XmlText textNode = bodyElement.SelectSingleNode("text()") as XmlText; + textNode.Value = "Original"; + + XmlTextTreeNode textTreeNode = bodyTreeNode.Nodes[0] as XmlTextTreeNode; + treeView.SelectedNode = textTreeNode; + InsertTextNodeBeforeCommand command = new InsertTextNodeBeforeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlTextTreeNode insertedTextTreeNode = bodyTreeNode.Nodes[0] as XmlTextTreeNode; + XmlText insertedTextNode = bodyElement.FirstChild as XmlText; + Assert.IsNotNull(insertedTextTreeNode); + Assert.AreEqual(2, bodyTreeNode.Nodes.Count); + Assert.AreEqual(String.Empty, insertedTextTreeNode.XmlText.Value); + Assert.IsNotNull(insertedTextNode); + Assert.AreEqual(2, bodyElement.ChildNodes.Count); + Assert.AreEqual(String.Empty, insertedTextNode.Value); + } + + /// + /// Makes sure that nothing happens if we try to add a text + /// node when there is no currently selected node. + /// + [Test] + public void InsertTextNodeWhenNoTreeNodeSelected() + { + treeView.SelectedNode = null; + XmlText newTextNode = doc.CreateTextNode(String.Empty); + treeView.InsertTextNodeBefore(newTextNode); + + XmlText textNode = bodyElement.SelectSingleNode("text()") as XmlText; + Assert.IsNull(textNode); + } + + [Test] + public void InsertTextNodeAfterWithNullOwner() + { + InsertTextNodeAfterCommand command = new InsertTextNodeAfterCommand(); + command.Run(); + } + + [Test] + public void InsertTextNodeAfter() + { + AddChildTextNode(); + + XmlText textNode = bodyElement.SelectSingleNode("text()") as XmlText; + textNode.Value = "OriginalTextNode"; + + XmlTextTreeNode textTreeNode = bodyTreeNode.Nodes[0] as XmlTextTreeNode; + treeView.SelectedNode = textTreeNode; + InsertTextNodeAfterCommand command = new InsertTextNodeAfterCommand(); + command.Owner = treeViewContainer; + command.Run(); + + XmlTextTreeNode insertedTextTreeNode = bodyTreeNode.LastNode as XmlTextTreeNode; + XmlText insertedTextNode = bodyElement.LastChild as XmlText; + Assert.IsNotNull(insertedTextTreeNode); + Assert.AreEqual(2, bodyTreeNode.Nodes.Count); + Assert.AreEqual(String.Empty, insertedTextTreeNode.XmlText.Value); + Assert.IsNotNull(insertedTextNode); + Assert.AreEqual(2, bodyElement.ChildNodes.Count); + Assert.AreEqual(String.Empty, insertedTextNode.Value); + } + + /// + /// Expect nothing to happen since the ICommand.Owner is not + /// set. + /// + [Test] + public void RemoveElementCommandWithNullOwner() + { + RemoveElementCommand command = new RemoveElementCommand(); + command.Run(); + } + + [Test] + public void RemoveRootElementUsingCommand() + { + treeView.SelectedNode = treeView.Nodes[0]; + + RemoveElementCommand command = new RemoveElementCommand(); + command.Owner = treeViewContainer; + command.Run(); + + Assert.AreEqual(0, treeView.Nodes.Count); + Assert.IsTrue(treeViewContainer.IsDirty); + } + + [Test] + public void RemoveTextNodeWithNullOwner() + { + RemoveTextNodeCommand command = new RemoveTextNodeCommand(); + command.Run(); + } + + [Test] + public void RemoveTextNode() + { + AddChildTextNode(); + + treeView.SelectedNode = bodyTreeNode.Nodes[0]; + + RemoveTextNodeCommand command = new RemoveTextNodeCommand(); + command.Owner = treeViewContainer; + command.Run(); + + Assert.IsFalse(bodyElement.HasChildNodes); + Assert.AreEqual(0, bodyTreeNode.Nodes.Count); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MouseDownTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MouseDownTestFixture.cs new file mode 100644 index 0000000000..0d24a0bf3c --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/MouseDownTestFixture.cs @@ -0,0 +1,93 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests that the XmlTreeView fires an AfterSelect event + /// when the user clicks into the XmlTreeView control but not + /// onto a node and deselects all nodes. The standard behaviour + /// of a tree control is to not fire an AfterSelect event in + /// this case. + /// + [TestFixture] + public class MouseDownTestFixture + { + DerivedXmlTreeViewControl treeView; + List treeViewEventArgs; + + [SetUp] + public void SetUpFixture() + { + treeViewEventArgs = new List(); + treeView = new DerivedXmlTreeViewControl(); + treeView.Height = 100; + treeView.Nodes.Add(new ExtTreeNode()); + treeView.AfterSelect += XmlTreeViewAfterSelect; + } + + [TearDown] + public void TearDownFixture() + { + if (treeView != null) { + treeView.AfterSelect -= XmlTreeViewAfterSelect; + treeView.Dispose(); + } + } + + /// + /// Make sure the AfterSelect event is not fired twice and the + /// standard behaviour of the OnMouseDown method is preserved + /// in the normal case. + /// + [Test] + public void MouseDownWithNodeSelected() + { + treeView.SelectedNode = treeView.Nodes[0]; + + // Make sure the button click will select the first node + // so choose x=0, y=0. + MouseEventArgs e = new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0); + treeView.CallMouseDown(e); + + Assert.IsNotNull(treeView.SelectedNode, "Sanity check: The mouse down call should not deselect the tree node."); + Assert.AreEqual(1, treeViewEventArgs.Count, "AfterSelect event should be fired once."); + } + + [Test] + public void MouseDownWithNoNodeSelected() + { + treeView.SelectedNode = null; + + // Make sure the mouse click will not select any + // tree node (x=0, y=99 - Height of control=100) + treeViewEventArgs.Clear(); + MouseEventArgs e = new MouseEventArgs(MouseButtons.Left, 1, 0, 99, 0); + treeView.CallMouseDown(e); + + Assert.IsNull(treeView.SelectedNode, "Sanity check: The mouse down call should not select a tree node"); + Assert.AreEqual(1, treeViewEventArgs.Count, "AfterSelect event should be fired once."); + TreeViewEventArgs treeViewEventArg = treeViewEventArgs[0]; + Assert.IsNull(treeViewEventArg.Node); + Assert.AreEqual(TreeViewAction.ByMouse, treeViewEventArg.Action); + } + + void XmlTreeViewAfterSelect(object sender, TreeViewEventArgs e) + { + treeViewEventArgs.Add(e); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/OwnerStatusTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/OwnerStatusTestFixture.cs new file mode 100644 index 0000000000..1d1065c402 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/OwnerStatusTestFixture.cs @@ -0,0 +1,119 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests the XmlTreeViewContainerControl.OwnerState property. + /// + [TestFixture] + public class OwnerStatusTestFixture + { + XmlTreeViewContainerControl treeViewContainer; + XmlTreeViewControl treeView; + XmlDocument doc; + XmlElementTreeNode htmlTreeNode; + XmlElementTreeNode bodyTreeNode; + XmlElementTreeNode paraTreeNode; + XmlTextTreeNode textTreeNode; + + [SetUp] + public void Init() + { + treeViewContainer = new XmlTreeViewContainerControl(); + + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + XmlSchemaCompletionData xhtmlSchema = new XmlSchemaCompletionData(reader); + XmlSchemaCompletionDataCollection schemas = new XmlSchemaCompletionDataCollection(); + XmlCompletionDataProvider provider = new XmlCompletionDataProvider(schemas, xhtmlSchema, String.Empty); + + treeViewContainer.LoadXml("

Text

", provider); + doc = treeViewContainer.Document; + treeView = treeViewContainer.TreeView; + + htmlTreeNode = (XmlElementTreeNode)treeView.Nodes[0]; + htmlTreeNode.Expanding(); + + bodyTreeNode = (XmlElementTreeNode)htmlTreeNode.Nodes[0]; + bodyTreeNode.Expanding(); + + paraTreeNode = (XmlElementTreeNode)bodyTreeNode.Nodes[0]; + paraTreeNode.Expanding(); + + textTreeNode = (XmlTextTreeNode)paraTreeNode.Nodes[0]; + } + + [TearDown] + public void TearDown() + { + if (treeViewContainer != null) { + treeViewContainer.Dispose(); + } + } + + [Test] + public void NothingSelected() + { + treeView.SelectedNode = null; + + Assert.AreEqual(XmlTreeViewContainerControl.XmlTreeViewContainerControlState.Nothing, + treeViewContainer.InternalState, + "OwnerState should be Nothing."); + } + + [Test] + public void RootElementSelected() + { + treeView.SelectedNode = htmlTreeNode; + + Assert.AreEqual(XmlTreeViewContainerControl.XmlTreeViewContainerControlState.RootElementSelected | XmlTreeViewContainerControl.XmlTreeViewContainerControlState.ElementSelected, + treeViewContainer.InternalState, + "OwnerState should be RootElementSelected and ElementSelected."); + } + + [Test] + public void BodyElementSelected() + { + treeView.SelectedNode = bodyTreeNode; + + Assert.AreEqual(XmlTreeViewContainerControl.XmlTreeViewContainerControlState.ElementSelected, + treeViewContainer.InternalState, + "OwnerState should be ElementSelected."); + } + + [Test] + public void ClassAttributeSelected() + { + treeView.SelectedNode = bodyTreeNode; + treeViewContainer.ShowAttributes(treeView.SelectedElement.Attributes); + + Assert.IsNotNull(treeViewContainer.AttributesGrid.SelectedGridItem, + "Sanity check - should have a grid item selected."); + + Assert.AreEqual(XmlTreeViewContainerControl.XmlTreeViewContainerControlState.ElementSelected | XmlTreeViewContainerControl.XmlTreeViewContainerControlState.AttributeSelected, + treeViewContainer.InternalState, + "OwnerState should be ElementSelected and AttributeSelected."); + } + + [Test] + public void TextNodeSelected() + { + treeView.SelectedNode = textTreeNode; + + Assert.AreEqual(XmlTreeViewContainerControl.XmlTreeViewContainerControlState.TextNodeSelected, + treeViewContainer.InternalState, + "OwnerState should be TextNodeSelected."); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementTestFixture.cs new file mode 100644 index 0000000000..7ad673816b --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementTestFixture.cs @@ -0,0 +1,97 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests that an element is removed from the XML document by the + /// XmlTreeEditor. + /// + [TestFixture] + public class RemoveElementTestFixture : XmlTreeViewTestFixtureBase + { + XmlElement bodyElement; + + [SetUp] + public void Init() + { + base.InitFixture(); + bodyElement = (XmlElement)editor.Document.SelectSingleNode("/html/body"); + mockXmlTreeView.SelectedElement = bodyElement; + + editor.RemoveElement(); + } + + [Test] + public void BodyElementRemoved() + { + Assert.IsNull(editor.Document.SelectSingleNode("/html/body")); + } + + [Test] + public void BodyElementRemovedFromTree() + { + Assert.AreEqual(1, mockXmlTreeView.ElementsRemoved.Count); + Assert.AreSame(bodyElement, mockXmlTreeView.ElementsRemoved[0]); + } + + [Test] + public void IsDirty() + { + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + [Test] + public void NoElementSelected() + { + mockXmlTreeView.SelectedElement = null; + mockXmlTreeView.IsDirty = false; + editor.RemoveElement(); + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + [Test] + public void RemoveRootElement() + { + XmlElement htmlElement = editor.Document.DocumentElement; + mockXmlTreeView.SelectedElement = htmlElement; + mockXmlTreeView.IsDirty = false; + editor.RemoveElement(); + Assert.IsTrue(mockXmlTreeView.IsDirty); + Assert.IsNull(editor.Document.DocumentElement); + } + + /// + /// Returns the xhtml strict schema as the default schema. + /// + protected override XmlSchemaCompletionData DefaultSchemaCompletionData { + get { + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + return new XmlSchemaCompletionData(reader); + } + } + + protected override string GetXml() + { + return "\r\n" + + "\t\r\n" + + "\t\t\r\n" + + "\t\r\n" + + "\t\r\n" + + "\t\r\n" + + ""; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementsFromTreeControlTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementsFromTreeControlTestFixture.cs new file mode 100644 index 0000000000..249941cb03 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveElementsFromTreeControlTestFixture.cs @@ -0,0 +1,90 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Xml; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.XmlEditor; +using NUnit.Framework; + +namespace XmlEditor.Tests.Tree +{ + [TestFixture] + public class RemoveElementsFromTreeControlTestFixture + { + XmlDocument doc; + XmlTreeViewContainerControl treeViewContainerControl; + XmlTreeViewControl treeView; + + [SetUp] + public void SetUp() + { + XmlCompletionDataProvider completionDataProvider = new XmlCompletionDataProvider(new XmlSchemaCompletionDataCollection(), null, String.Empty); + treeViewContainerControl = new XmlTreeViewContainerControl(); + treeView = treeViewContainerControl.TreeView; + treeViewContainerControl.LoadXml("", completionDataProvider); + doc = treeViewContainerControl.Document; + } + + [TearDown] + public void TearDown() + { + if (treeViewContainerControl != null) { + treeViewContainerControl.Dispose(); + } + } + + [Test] + public void IsDirty() + { + Assert.IsFalse(treeViewContainerControl.IsDirty); + } + + [Test] + public void RootTreeNodesBeforeRemove() + { + Assert.AreEqual(1, treeView.Nodes.Count); + } + + [Test] + public void RemoveSelectedRootElement() + { + treeView.SelectedNode = treeView.Nodes[0]; + treeView.RemoveElement(doc.DocumentElement); + Assert.AreEqual(0, treeView.Nodes.Count); + } + + [Test] + public void RemoveRootElementWhenNoTreeNodeSelected() + { + treeView.SelectedNode = null; + treeView.RemoveElement(doc.DocumentElement); + Assert.AreEqual(0, treeView.Nodes.Count); + } + + [Test] + public void RemoveChildElement() + { + ExtTreeNode rootNode = (ExtTreeNode)treeView.Nodes[0]; + rootNode.Expanding(); + treeView.RemoveElement((XmlElement)doc.DocumentElement.FirstChild); + Assert.AreEqual(0, treeView.Nodes[0].Nodes.Count); + } + + /// + /// Removing an element that does not exist in the + /// tree should not make the view dirty. Nothing should + /// happen at all. + /// + [Test] + public void RemoveUnknownElement() + { + XmlElement element = (XmlElement)doc.CreateElement("NewElement"); + treeView.RemoveElement(element); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodeTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodeTestFixture.cs new file mode 100644 index 0000000000..cffe6bf224 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodeTestFixture.cs @@ -0,0 +1,90 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Tests that a text node is removed from the XML document by the + /// XmlTreeEditor. + /// + [TestFixture] + public class RemoveTextNodeTestFixture : XmlTreeViewTestFixtureBase + { + XmlElement paragraphElement; + + [SetUp] + public void Init() + { + base.InitFixture(); + paragraphElement = (XmlElement)editor.Document.SelectSingleNode("/html/body/p"); + XmlText textNode = (XmlText)paragraphElement.FirstChild; + mockXmlTreeView.SelectedTextNode = textNode; + + editor.RemoveTextNode(); + } + + [Test] + public void TextNodeRemovedFromDocument() + { + Assert.AreEqual(0, paragraphElement.ChildNodes.Count); + } + + /// + /// Tests that the xml tree editor does not throw + /// an exception if we try to remove a text node when + /// no node is selected. + /// + [Test] + public void NoTextNodeSelected() + { + mockXmlTreeView.IsDirty = false; + mockXmlTreeView.SelectedTextNode = null; + editor.RemoveTextNode(); + + Assert.IsFalse(mockXmlTreeView.IsDirty); + } + + [Test] + public void TextNodeRemovedFromView() + { + Assert.AreEqual(1, mockXmlTreeView.TextNodesRemoved.Count); + } + + [Test] + public void IsDirty() + { + Assert.IsTrue(mockXmlTreeView.IsDirty); + } + + /// + /// Returns the xhtml strict schema as the default schema. + /// + protected override XmlSchemaCompletionData DefaultSchemaCompletionData { + get { + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + return new XmlSchemaCompletionData(reader); + } + } + + protected override string GetXml() + { + return "\r\n" + + "\t\r\n" + + "\t\t

some text here

\r\n" + + "\t\r\n" + + ""; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodesFromTreeControlTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodesFromTreeControlTestFixture.cs new file mode 100644 index 0000000000..dc9a2f3a74 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RemoveTextNodesFromTreeControlTestFixture.cs @@ -0,0 +1,105 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; +using System.Xml; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.XmlEditor; +using NUnit.Framework; + +namespace XmlEditor.Tests.Tree +{ + [TestFixture] + public class RemoveTextNodesFromTreeControlTestFixture + { + XmlDocument doc; + XmlTreeViewContainerControl treeViewContainerControl; + XmlTreeViewControl treeView; + XmlElementTreeNode topElementTreeNode; + XmlElementTreeNode childElementTreeNode; + XmlTextTreeNode topTextTreeNode; + + [SetUp] + public void SetUp() + { + XmlCompletionDataProvider completionDataProvider = new XmlCompletionDataProvider(new XmlSchemaCompletionDataCollection(), null, String.Empty); + treeViewContainerControl = new XmlTreeViewContainerControl(); + treeView = treeViewContainerControl.TreeView; + treeViewContainerControl.LoadXml("texttext", completionDataProvider); + doc = treeViewContainerControl.Document; + + ExtTreeNode rootNode = (ExtTreeNode)treeView.Nodes[0]; + rootNode.Expanding(); + + topElementTreeNode = (XmlElementTreeNode)rootNode.Nodes[0]; + topElementTreeNode.Expanding(); + + topTextTreeNode = (XmlTextTreeNode)topElementTreeNode.Nodes[0]; + + ExtTreeNode bottomNode = (ExtTreeNode)rootNode.Nodes[1]; + bottomNode.Expanding(); + + childElementTreeNode = (XmlElementTreeNode)bottomNode.Nodes[0]; + childElementTreeNode.Expanding(); + } + + [TearDown] + public void TearDown() + { + if (treeViewContainerControl != null) { + treeViewContainerControl.Dispose(); + } + } + + [Test] + public void RemoveTextNode() + { + treeView.SelectedNode = topTextTreeNode; + treeView.RemoveTextNode(topTextTreeNode.XmlText); + + Assert.AreEqual(0, topElementTreeNode.Nodes.Count); + } + + /// + /// Makes sure that nothing happens if we try to remove a text + /// node when there is no currently selected node. + /// + [Test] + public void RemoveTextNodeWhenNoTreeNodeSelected() + { + treeView.SelectedNode = null; + XmlText newTextNode = doc.CreateTextNode(String.Empty); + treeView.RemoveTextNode(newTextNode); + + Assert.AreEqual(1, topElementTreeNode.Nodes.Count); + } + + /// + /// Makes sure that nothing happens if we try to remove a text + /// node that is not in the tree. + /// + [Test] + public void RemoveUnknownTextNode() + { + treeView.SelectedNode = topElementTreeNode; + XmlText newTextNode = doc.CreateTextNode(String.Empty); + treeView.RemoveTextNode(newTextNode); + + Assert.AreEqual(1, topElementTreeNode.Nodes.Count); + } + + [Test] + public void RemoveKnownTextNodeWhenNothingSelected() + { + treeView.SelectedNode = null; + treeView.RemoveTextNode(topTextTreeNode.XmlText); + + Assert.AreEqual(0, topElementTreeNode.Nodes.Count); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RootNodeAddedToTreeControlTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RootNodeAddedToTreeControlTestFixture.cs index 152135a6a3..e7aa27b431 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RootNodeAddedToTreeControlTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/RootNodeAddedToTreeControlTestFixture.cs @@ -22,22 +22,29 @@ namespace XmlEditor.Tests.Tree XmlDocument doc; XmlElement initialElementSelected; bool initialIsElementSelected; + XmlNode documentElement; [TestFixtureSetUp] public void SetUpFixture() { - doc = new XmlDocument(); - doc.LoadXml(""); - using (XmlTreeViewControl treeView = new XmlTreeViewControl()) { - treeView.DocumentElement = doc.DocumentElement; + using (XmlTreeViewContainerControl treeViewContainer = new XmlTreeViewContainerControl()) { + + XmlCompletionDataProvider completionDataProvider = new XmlCompletionDataProvider(new XmlSchemaCompletionDataCollection(), null, String.Empty); + treeViewContainer.LoadXml("", completionDataProvider); + + doc = treeViewContainer.Document; + XmlTreeViewControl treeView = treeViewContainer.TreeView; + + treeViewContainer.DocumentElement = doc.DocumentElement; initialElementSelected = treeView.SelectedElement; initialIsElementSelected = treeView.IsElementSelected; // Set the document element again to make sure the existing node // is removed. doc.LoadXml(""); - treeView.DocumentElement = null; - treeView.DocumentElement = doc.DocumentElement; + treeViewContainer.DocumentElement = null; + treeViewContainer.DocumentElement = doc.DocumentElement; + documentElement = treeViewContainer.DocumentElement; rootNode = (XmlElementTreeNode)treeView.Nodes[0]; nodeCount = treeView.Nodes.Count; @@ -85,5 +92,11 @@ namespace XmlEditor.Tests.Tree { Assert.IsTrue(Object.ReferenceEquals(rootNode.XmlElement, doc.DocumentElement)); } + + [Test] + public void DocumentElement() + { + Assert.AreSame(doc.DocumentElement, documentElement); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/TextNodeTextChangedTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/TextNodeTextChangedTestFixture.cs index c2aed72d64..457e55fbc8 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/TextNodeTextChangedTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/TextNodeTextChangedTestFixture.cs @@ -74,6 +74,17 @@ namespace XmlEditor.Tests.Tree Assert.IsFalse(mockXmlTreeView.IsDirty); } + /// + /// Check that the Xml tree editor calls the XmlTreeView's + /// UpdateTextNode method. + /// + [Test] + public void TreeNodeTextUpdated() + { + Assert.AreEqual(1, mockXmlTreeView.TextNodesUpdated.Count); + Assert.AreEqual(textNode, mockXmlTreeView.TextNodesUpdated[0]); + } + protected override string GetXml() { return "text"; diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlAttributeTypeDescriptorTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlAttributeTypeDescriptorTestFixture.cs index 01baf763c5..6a6f4ed02e 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlAttributeTypeDescriptorTestFixture.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlAttributeTypeDescriptorTestFixture.cs @@ -46,5 +46,32 @@ namespace XmlEditor.Tests.Tree { Assert.IsTrue(Object.ReferenceEquals(typeDescriptor, typeDescriptor.GetPropertyOwner(null))); } + + [Test] + public void ComponentName() + { + Assert.IsNull(typeDescriptor.GetComponentName()); + } + + [Test] + public void DefaultEvent() + { + Assert.IsNull(typeDescriptor.GetDefaultEvent()); + } + + [Test] + public void Events() + { + Assert.IsNull(typeDescriptor.GetEvents()); + Assert.IsNull(typeDescriptor.GetEvents(new Attribute[0])); + } + + [Test] + public void NullAttributesCollection() + { + XmlAttributeTypeDescriptor typeDescriptor = new XmlAttributeTypeDescriptor(null); + PropertyDescriptorCollection properties = typeDescriptor.GetProperties(); + Assert.AreEqual(0, properties.Count); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTextTreeNodeTextTests.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTextTreeNodeTextTests.cs index f336c5f205..82e22e3f4c 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTextTreeNodeTextTests.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTextTreeNodeTextTests.cs @@ -55,5 +55,13 @@ namespace XmlEditor.Tests.Tree XmlTextTreeNode node = new XmlTextTreeNode(text); Assert.AreEqual("Test...", node.Text); } + + [Test] + public void EmptyLines() + { + XmlText text = doc.CreateTextNode("\r\n\r\n\r\n"); + XmlTextTreeNode node = new XmlTextTreeNode(text); + Assert.AreEqual(String.Empty, node.Text); + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewContainerTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewContainerTestFixture.cs new file mode 100644 index 0000000000..21d153bc79 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Tree/XmlTreeViewContainerTestFixture.cs @@ -0,0 +1,334 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; +using System.Xml; + +using ICSharpCode.XmlEditor; +using NUnit.Framework; +using XmlEditor.Tests.Utils; + +namespace XmlEditor.Tests.Tree +{ + /// + /// Various tests for the XmlTreeViewContainerControl. These + /// tests do not really fit into any other test fixture. + /// + [TestFixture] + public class XmlTreeViewContainerTestFixture + { + XmlDocument doc; + XmlTreeViewControl treeView; + DerivedXmlTreeViewContainerControl treeViewContainer; + RichTextBox textBox; + XmlCompletionDataProvider provider; + PropertyGrid attributesGrid; + SplitContainer splitContainer; + RichTextBox errorMessageTextBox; + bool dirtyChanged; + XmlElementTreeNode htmlTreeNode; + XmlTextTreeNode textTreeNode; + + [SetUp] + public void Init() + { + treeViewContainer = new DerivedXmlTreeViewContainerControl(); + treeViewContainer.DirtyChanged += TreeViewContainerDirtyChanged; + + XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema(); + XmlSchemaCompletionData xhtmlSchema = new XmlSchemaCompletionData(reader); + XmlSchemaCompletionDataCollection schemas = new XmlSchemaCompletionDataCollection(); + provider = new XmlCompletionDataProvider(schemas, xhtmlSchema, String.Empty); + + treeViewContainer.LoadXml("text", provider); + doc = treeViewContainer.Document; + treeView = treeViewContainer.TreeView; + + htmlTreeNode = (XmlElementTreeNode)treeView.Nodes[0]; + htmlTreeNode.Expanding(); + textTreeNode = (XmlTextTreeNode)htmlTreeNode.Nodes[0]; + + splitContainer = (SplitContainer)treeViewContainer.Controls["splitContainer"]; + + textBox = (RichTextBox)splitContainer.Panel2.Controls["textBox"]; + errorMessageTextBox = (RichTextBox)splitContainer.Panel2.Controls["errorMessageTextBox"]; + attributesGrid = (PropertyGrid)splitContainer.Panel2.Controls["attributesGrid"]; + } + + [TearDown] + public void TearDown() + { + if (treeViewContainer != null) { + treeViewContainer.DirtyChanged -= TreeViewContainerDirtyChanged; + treeViewContainer.Dispose(); + } + } + + [Test] + public void ErrorMessageTextBoxVisibleAtStart() + { + Assert.IsFalse(treeViewContainer.IsErrorMessageTextBoxVisible); + } + + [Test] + public void TextBoxIsNotTabStopAtStart() + { + Assert.IsFalse(textBox.TabStop); + } + + [Test] + public void TextBoxIsEmptyAtStart() + { + Assert.AreEqual(String.Empty, textBox.Text); + } + + [Test] + public void AttributesGridIsTabStopAtStart() + { + Assert.IsTrue(attributesGrid.TabStop); + } + + /// + /// Check that the XmlTreeViewContainer brought the + /// AttributesGrid to the front. + /// + [Test] + public void AttributesGridOnTop() + { + Assert.AreEqual(0, splitContainer.Panel2.Controls.IndexOf(attributesGrid), + "AttributesGrid is not on top"); + } + + /// + /// Checks that the text box shows the specified text and + /// is visible in the control. + /// + [Test] + public void ShowTextContent() + { + string text = "test"; + treeViewContainer.ShowTextContent(text); + + Assert.AreEqual(text, treeViewContainer.TextContent); + Assert.AreEqual(text, textBox.Text); + Assert.IsTrue(textBox.TabStop); + Assert.AreEqual(0, splitContainer.Panel2.Controls.IndexOf(textBox)); + } + + [Test] + public void TextBoxClearedAfterLoadXml() + { + treeViewContainer.ShowTextContent("test"); + treeViewContainer.LoadXml("", provider); + + Assert.AreEqual(String.Empty, textBox.Text); + AttributesGridOnTop(); + } + + [Test] + public void RootNodeExpanded() + { + Assert.IsTrue(treeView.Nodes[0].IsExpanded); + } + + [Test] + public void AttributesClearedAfterLoadXml() + { + // Make sure some attributes are showing. + treeViewContainer.ShowAttributes(doc.DocumentElement.Attributes); + + Assert.IsTrue(doc.DocumentElement.HasAttributes, "Sanity check that the root element has some attributes"); + Assert.IsNotNull(attributesGrid.SelectedObject); + + // Loading new xml should clear the attributes grid. + treeViewContainer.LoadXml("", provider); + + Assert.IsNull(attributesGrid.SelectedObject, + "Should be no SelectedObject in the attributes grid after loading new xml."); + } + + [Test] + public void ErrorMessageTextBoxNotTabStop() + { + Assert.IsFalse(errorMessageTextBox.TabStop); + } + + [Test] + public void ErrorMessageTextBoxNotOnTop() + { + Assert.AreNotEqual(0, splitContainer.Panel2.Controls.IndexOf(errorMessageTextBox)); + } + + [Test] + public void ShowXmlNotWellFormed() + { + XmlException ex = new XmlException("Message"); + treeViewContainer.ShowXmlIsNotWellFormedMessage(ex); + + Assert.AreEqual(0, treeView.Nodes.Count, "TreeView should be cleared."); + Assert.AreEqual(ex.Message, treeViewContainer.ErrorMessage); + Assert.AreEqual(0, splitContainer.Panel2.Controls.IndexOf(errorMessageTextBox), "ErrorMessageTextBox should be on top"); + Assert.AreEqual(ex.Message, errorMessageTextBox.Text); + Assert.IsTrue(errorMessageTextBox.TabStop); + Assert.IsFalse(attributesGrid.TabStop); + Assert.IsFalse(textBox.TabStop); + } + + /// + /// Checks that the text box is not a tab stop after showing + /// an error. + /// + [Test] + public void ShowTextContentBeforeShowingError() + { + treeViewContainer.ShowTextContent("Test"); + ShowXmlNotWellFormed(); + } + + [Test] + public void DirtyChanged() + { + treeViewContainer.IsDirty = true; + Assert.IsTrue(dirtyChanged); + } + + [Test] + public void TextChanged() + { + // Select the text node. + treeView.SelectedNode = textTreeNode; + + string newText = "changed text"; + textBox.Text = newText; + + // Make sure the dirty flag is changed by changing + // the text. + treeViewContainer.IsDirty = false; + dirtyChanged = false; + + treeViewContainer.CallTextBoxTextChanged(); + + Assert.AreEqual(newText, textTreeNode.XmlText.Value); + Assert.AreEqual(newText, textTreeNode.Text, "Tree node text should be updated with new XmlText's value"); + Assert.IsTrue(treeViewContainer.IsDirty); + Assert.IsTrue(dirtyChanged); + } + + /// + /// Tests that when the XmlTreeView's UpdateTextNode method + /// is called we do not get a null exception if the + /// text node cannot be found in the tree. + /// + [Test] + public void UpdateUnknownTextNodeText() + { + // Select the text node. + treeView.SelectedNode = textTreeNode; + + XmlText textNode = doc.CreateTextNode(String.Empty); + treeView.UpdateTextNode(textNode); + } + + /// + /// Updates the text node when no text node is selected in the + /// tree. + /// + [Test] + public void UpdateTextNodeText() + { + treeView.SelectedNode = null; + + textTreeNode.XmlText.Value = "New value"; + treeView.UpdateTextNode(textTreeNode.XmlText); + Assert.AreEqual("New value", textTreeNode.Text); + } + + + /// + /// Check that the DirtyChanged event is not fired + /// + [Test] + public void TextChangedDirtyUnchanged() + { + // Select the text node. + treeView.SelectedNode = textTreeNode; + + textBox.Text = "changed text"; + + // Make sure the dirty flag is changed by changing + // the text. + treeViewContainer.IsDirty = true; + dirtyChanged = false; + + treeViewContainer.CallTextBoxTextChanged(); + + Assert.AreEqual("changed text", textTreeNode.XmlText.Value); + Assert.IsTrue(treeViewContainer.IsDirty); + Assert.IsFalse(dirtyChanged); + } + + [Test] + public void AttributeValueChanged() + { + // Select the html node. + treeView.SelectedNode = htmlTreeNode; + treeViewContainer.ShowAttributes(doc.DocumentElement.Attributes); + + Assert.IsNotNull(attributesGrid.SelectedGridItem); + + treeViewContainer.IsDirty = false; + dirtyChanged = false; + treeViewContainer.CallAttributesGridPropertyValueChanged(); + + Assert.IsTrue(treeViewContainer.IsDirty); + Assert.IsTrue(dirtyChanged); + } + + [Test] + public void AttributeValueChangedDirtyUnchanged() + { + // Select the html node. + treeView.SelectedNode = htmlTreeNode; + treeViewContainer.ShowAttributes(doc.DocumentElement.Attributes); + + Assert.IsNotNull(attributesGrid.SelectedGridItem); + + treeViewContainer.IsDirty = true; + dirtyChanged = false; + treeViewContainer.CallAttributesGridPropertyValueChanged(); + + Assert.IsTrue(treeViewContainer.IsDirty); + Assert.IsFalse(dirtyChanged); + } + + [Test] + public void TextNodeSelected() + { + treeView.SelectedNode = textTreeNode; + treeViewContainer.ShowTextContent(String.Empty); + treeViewContainer.CallXmlElementTreeViewAfterSelect(); + + Assert.AreEqual("text", textBox.Text); + } + + [Test] + public void HtmlElementNodeSelected() + { + treeView.SelectedNode = htmlTreeNode; + treeViewContainer.CallXmlElementTreeViewAfterSelect(); + + Assert.IsNotNull(attributesGrid.SelectedGridItem); + Assert.AreEqual("id", attributesGrid.SelectedGridItem.Label); + } + + void TreeViewContainerDirtyChanged(object source, EventArgs e) + { + dirtyChanged = true; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeView.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeView.cs new file mode 100644 index 0000000000..26a5c50f6f --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeView.cs @@ -0,0 +1,29 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Forms; +using ICSharpCode.XmlEditor; + +namespace XmlEditor.Tests.Utils +{ + /// + /// Test utility class that has the XmlTreeViewControl as a base class + /// and gives access to protected methods. + /// + public class DerivedXmlTreeViewControl : XmlTreeViewControl + { + public DerivedXmlTreeViewControl() + { + } + + public void CallMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeViewContainerControl.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeViewContainerControl.cs new file mode 100644 index 0000000000..b6c86831ee --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/DerivedXmlTreeViewContainerControl.cs @@ -0,0 +1,125 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +using ICSharpCode.XmlEditor; + +namespace XmlEditor.Tests.Utils +{ + /// + /// Derived version of the XmlTreeViewContainerControl which + /// allows us to override the code that shows the various dialogs + /// that ask for user input so we can fake the data allowing us + /// to test the class. + /// + public class DerivedXmlTreeViewContainerControl : XmlTreeViewContainerControl + { + List addElementDialogElementNamesReturned = new List(); + DialogResult addElementDialogResult = DialogResult.OK; + List addAttributeDialogAttributeNamesReturned = new List(); + DialogResult addAttributeDialogResult = DialogResult.OK; + + /// + /// This is the list of element names that will be returned from + /// the mock AddElementDialog. + /// + public List AddElementDialogElementNamesReturned { + get { + return addElementDialogElementNamesReturned; + } + } + + /// + /// Gets or sets the dialog result for the AddElementDialog. + /// + public DialogResult AddElementDialogResult { + get { + return addElementDialogResult; + } + set { + addElementDialogResult = value; + } + } + + /// + /// Gets the list of attribute names that will be returned + /// from the mock AddAttributeDialog. + /// + public List AddAttributeDialogAttributeNamesReturned { + get { + return addAttributeDialogAttributeNamesReturned; + } + } + + /// + /// Gets or sets the dialog result for the AddAttributeDialog. + /// + public DialogResult AddAttributeDialogResult { + get { + return addAttributeDialogResult; + } + set { + addAttributeDialogResult = value; + } + } + + /// + /// Allows us to call the XmlTreeViewContainerControl's + /// TextBoxChanged method to fake the user typing in text + /// into the text box. + /// + public void CallTextBoxTextChanged() + { + base.TextBoxTextChanged(this, new EventArgs()); + } + + /// + /// Allows us to call the XmlTreeViewContainerControl's + /// AttributesGridPropertyValueChanged to fake the user + /// changing the property value. + /// + public void CallAttributesGridPropertyValueChanged() + { + base.AttributesGridPropertyValueChanged(this, new PropertyValueChangedEventArgs(null, null)); + } + + /// + /// Allows us to call the XmlTreeViewContainerControl's + /// XmlElementTreeViewAfterSelect to fake the user selecting + /// a tree node. + /// + public void CallXmlElementTreeViewAfterSelect() + { + base.XmlElementTreeViewAfterSelect(this, new TreeViewEventArgs(null, TreeViewAction.ByMouse)); + } + + /// + /// Returns a new MockAddElementDialog for testing. + /// + protected override IAddElementDialog CreateAddElementDialog(string[] elementNames) + { + MockAddElementDialog dialog = new MockAddElementDialog(); + dialog.SetElementNamesToReturn(addElementDialogElementNamesReturned.ToArray()); + dialog.SetDialogResult(addElementDialogResult); + return dialog; + } + + /// + /// Returns a new MockAddAttributeDialog for testing. + /// + protected override IAddAttributeDialog CreateAddAttributeDialog(string[] attributeNames) + { + MockAddAttributeDialog dialog = new MockAddAttributeDialog(); + dialog.SetAttributeNamesToReturn(addAttributeDialogAttributeNamesReturned.ToArray()); + dialog.SetDialogResult(addAttributeDialogResult); + return dialog; + } + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddAttributeDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddAttributeDialog.cs new file mode 100644 index 0000000000..acdc4fe960 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddAttributeDialog.cs @@ -0,0 +1,65 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using ICSharpCode.XmlEditor; + +namespace XmlEditor.Tests.Utils +{ + /// + /// Mocks the AddAttributeDialog so we can test the + /// XmlTreeViewContainerControl class when it displays + /// the AddAttributeDialog. + /// + public class MockAddAttributeDialog : IAddAttributeDialog + { + DialogResult dialogResult = DialogResult.OK; + List attributeNames = new List(); + + /// + /// Specifies the attribute names to return from the + /// IAddAttributeDialog.AttributeNames property. + /// + public void SetAttributeNamesToReturn(string[] names) + { + attributeNames.Clear(); + foreach (string name in names) { + attributeNames.Add(name); + } + } + + /// + /// Specifies the dialog result to return from the + /// IAddAttributeDialog.ShowDialog method. + /// + public void SetDialogResult(DialogResult result) + { + dialogResult = result; + } + + #region IAddAttributeDialog implementation + + public string[] AttributeNames { + get { + return attributeNames.ToArray(); + } + } + + public DialogResult ShowDialog() + { + return dialogResult; + } + + public void Dispose() + { + } + + #endregion + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddElementDialog.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddElementDialog.cs new file mode 100644 index 0000000000..314864fbe9 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockAddElementDialog.cs @@ -0,0 +1,65 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using ICSharpCode.XmlEditor; + +namespace XmlEditor.Tests.Utils +{ + /// + /// Mocks the AddElementDialog so we can test the + /// XmlTreeViewContainerControl class when it displays + /// the AddElementDialog. + /// + public class MockAddElementDialog : IAddElementDialog + { + DialogResult dialogResult = DialogResult.OK; + List elementNames = new List(); + + /// + /// Specifies the element names to return from the + /// IAddElementDialog.ElementNames property. + /// + public void SetElementNamesToReturn(string[] names) + { + elementNames.Clear(); + foreach (string name in names) { + elementNames.Add(name); + } + } + + /// + /// Specifies the dialog result to return from the + /// IAddElementDialog.ShowDialog method. + /// + public void SetDialogResult(DialogResult result) + { + dialogResult = result; + } + + #region IAddElementDialog implementation + + public string[] ElementNames { + get { + return elementNames.ToArray(); + } + } + + public DialogResult ShowDialog() + { + return dialogResult; + } + + public void Dispose() + { + } + + #endregion + } +} diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockXmlTreeView.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockXmlTreeView.cs index fc60650226..0fb67eeee7 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockXmlTreeView.cs +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockXmlTreeView.cs @@ -32,6 +32,12 @@ namespace XmlEditor.Tests.Utils List childElementsAdded = new List(); List elementsInsertedBefore = new List(); List elementsInsertedAfter = new List(); + List elementsRemoved = new List(); + List childTextNodesAdded = new List(); + List textNodesInsertedBefore = new List(); + List textNodesInsertedAfter = new List(); + List textNodesRemoved = new List(); + List textNodesUpdated = new List(); public MockXmlTreeView() { @@ -134,7 +140,37 @@ namespace XmlEditor.Tests.Utils { elementsInsertedAfter.Add(element); } + + public void RemoveElement(XmlElement element) + { + elementsRemoved.Add(element); + } + public void AppendChildTextNode(XmlText textNode) + { + childTextNodesAdded.Add(textNode); + } + + public void InsertTextNodeBefore(XmlText textNode) + { + textNodesInsertedBefore.Add(textNode); + } + + public void InsertTextNodeAfter(XmlText textNode) + { + textNodesInsertedAfter.Add(textNode); + } + + public void RemoveTextNode(XmlText textNode) + { + textNodesRemoved.Add(textNode); + } + + public void UpdateTextNode(XmlText textNode) + { + textNodesUpdated.Add(textNode); + } + public string TextContent { get { return textContentDisplayed; @@ -261,5 +297,65 @@ namespace XmlEditor.Tests.Utils return elementsInsertedAfter; } } + + /// + /// Returns the elements removed via the RemoveElement + /// method. + /// + public List ElementsRemoved { + get { + return elementsRemoved; + } + } + + /// + /// Returns the text nodes added via the AppendChildTextNode + /// method. + /// + public List ChildTextNodesAdded { + get { + return childTextNodesAdded; + } + } + + /// + /// Returns the text nodes that were inserted via the + /// InsertTextNodeBefore method. + /// + public List TextNodesInsertedBefore { + get { + return textNodesInsertedBefore; + } + } + + /// + /// Returns the text nodes that were inserted via the + /// InsertTextNodeAfter method. + /// + public List TextNodesInsertedAfter { + get { + return textNodesInsertedAfter; + } + } + + /// + /// Returns the text nodes that were removed via the + /// RemoveTextNode method. + /// + public List TextNodesRemoved { + get { + return textNodesRemoved; + } + } + + /// + /// Returns the text nodes that were updated via the + /// UpdateTextNode method. + /// + public List TextNodesUpdated { + get { + return textNodesUpdated; + } + } } } diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj index 9a1ec1a917..bdd539bcf9 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj @@ -70,6 +70,21 @@ + + + + + + + + + + + + + + + @@ -143,6 +158,7 @@ +
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/app.config b/src/AddIns/DisplayBindings/XmlEditor/Test/app.config new file mode 100644 index 0000000000..f1f39768e4 --- /dev/null +++ b/src/AddIns/DisplayBindings/XmlEditor/Test/app.config @@ -0,0 +1,13 @@ + + + +
+ + + + + + + + + diff --git a/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln b/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln index 5be32fb821..98e3aeda9e 100644 --- a/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln +++ b/src/AddIns/DisplayBindings/XmlEditor/XmlEditor.sln @@ -1,5 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# SharpDevelop 2.0.0.1590 + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +# SharpDevelop 2.1.0.2075 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor.Tests", "Test\XmlEditor.Tests.csproj", "{FC0FE702-A87D-4D70-A9B6-1ECCD611125F}"