Visual Studio, Testing, XLinq and Html Generation

My fpnotebook site is compiled from a plain text database into html.  The database started on a handheld HP 200lx (great device) and I would export the data, import into Access and run various versions of code to generate the html.  Ten years later, I take notes on a Laptop in my WPF/C# homegrown notetaker application using MS SQL, and then generate the html  in another wpf/C# program.

Linq to XML (and especially the Lambda equation versions) have made generating html elegant.  Recently I needed to split an html list in two (“ul – li li”  into “ul – li” and “ul – li” ) regardless of the parent container (ul, ol, dt, div…) or the children (li, p, dd…)  or the attributes on either.

Using XLinq for this is trivial.  But what makes it even better is the process.  I started programming in 1983 and have developed plenty of bad habits and missed quite a bit of formal training.  Test Driven Development  and unit testing in general does not come to me naturally.  However, Visual Studio even without add-ons has made this very easy, and I’m an idiot when I do not incorporate this.

Although Visual Studio has the generate stub method, I prefer to place my procedure in exactly  the correct region with the parameters as I want them, and then use the “generate unit test” dialog.  So I wrote my test:

        [TestMethod()]
        public void SplitList11()
        {
            XElement xListIn = XElement.Parse(@"
								<ul>
									<li><a href=""#"">Clinical Pearls</a></li>
									<li><a href=""#"">Clinical Research</a></li>
									<li><a href=""#"">Employment</a></li>
									<li><a href=""#"">Examination</a></li>
									<li><a href=""#"">General</a></li>
									<li><a href=""#"">Geriatric Medicine</a></li>
									<li><a href=""#"">Malpractice</a></li>
									<li><a href=""#"">Medical Informatics</a></li>
									<li><a href=""#"">Pharmacology</a></li>
									<li><a href=""#"">Provider Billing</a></li>
									<li><a href=""#"">Style</a></li>
								</ul>
                   ");
            XElement expected = XElement.Parse(@"
 							<div>
								<ul>
									<li><a href=""#"">Clinical Pearls</a></li>
									<li><a href=""#"">Clinical Research</a></li>
									<li><a href=""#"">Employment</a></li>
									<li><a href=""#"">Examination</a></li>
									<li><a href=""#"">General</a></li>
									<li><a href=""#"">Geriatric Medicine</a></li>
								</ul>
								<ul>
									<li><a href=""#"">Malpractice</a></li>
									<li><a href=""#"">Medical Informatics</a></li>
									<li><a href=""#"">Pharmacology</a></li>
									<li><a href=""#"">Provider Billing</a></li>
									<li><a href=""#"">Style</a></li>
								</ul>
							</div>
                   ");
            XElement actual;
            actual = xmlHelper.SplitList(xListIn);

            Console.WriteLine("==  Original List ==");
            Console.WriteLine("====================");
            Console.WriteLine(xListIn);

            Console.WriteLine("");
            Console.WriteLine("==  Split List ==");
            Console.WriteLine("=================");
            Console.WriteLine(actual);
           Assert.IsTrue(XNode.DeepEquals(expected, actual));

         }

Note that the Console.WriteLine will output into the test details as long as the test does not fail before that point.  This really helps to get the test to pass.

And here is the actual code to do the split:

       /// <summary>
        /// Split a xml list (e.g UL or OL) into 2 lists and enclose inside of a parent element 
        /// </summary>
        /// <param name="xListIn">original list (ul.li li)</param>
        /// <param name="newParentName">parent element name</param>
        /// <returns>2 lists inside of an enclosing parent (div.ul.li ul.li)</returns>
        public static XElement SplitList(XElement xListIn,string newParentName="div")
        {
            //Determine total number of child items
            int nItems = xListIn.Elements().Count();
            //Determine the number of items in list1 (should contain half or half+1 items)
            int nItems1 =  (int)Math.Ceiling((double)nItems/2);

            //Create list1 and remove the second half of the list
            XElement xList1 = new XElement(xListIn);
            xList1.Elements().Skip(nItems1).Remove();

            //Create list2 and remove the first half of the list
            XElement xList2 = new XElement(xListIn);
            xList2.Elements().Take(nItems1).Remove();

            //Add list1 and list2 to a parent element
            XElement xDiv = new XElement(newParentName, xList1, xList2);

            return xDiv;
        }
Advertisements
This entry was posted in Coding, Uncategorized. Bookmark the permalink.