|
Red Squirrel Reflections
Dave Hoover explores the psychology of software development
|
|
Fri, 28 Jan 2005Quote Manager Project -- Day 10 An ongoing pet project blog...
So I RTFM and found that you can add XML
Node root = document.getElementsByTagName("quotes").item(0);
Node quoteNode = document.createElement("quote");
root.appendChild(quoteNode);
That passes the test.
I should have this task completed in (as my buddy Jeff says) two shakes of a lamb's tail.
I'm going to make the test a bit more rigorous...
public void testShouldWriteXmlWhenGivenNewQuote() throws Exception {
String text = "Program to an interface, not an implementation.";
String isbn = "0201633612";
String title = "Design Patterns";
String firstName = "Gang";
String lastName = "of Four";
String url = "http://c2.com/cgi/wiki?GangOfFour";
Collection<Person> authors = new ArrayList<Person>(1);
authors.add(new Person(firstName, lastName, url));
Quote quote = new Quote(text, new Source(title, "", isbn), authors, null);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("stub.xml");
assertEquals(0, document.getElementsByTagName("quote").getLength());
Manager manager = new XmlQuoteManager(document);
manager.newQuote(quote);
assertEquals(1, document.getElementsByTagName("quote").getLength());
String textContent = documentToText(document);
assertTrue(-1 != textContent.indexOf("<text>" + text + "</text>"));
}
Not a lot more rigor, but I want to take small steps.
The documentToText method is boring so I left it out.
The test is failing.
I just need to add a text Node to the quote Node. Like so...
public void newQuote(Quote quote) {
Node root = document.getElementsByTagName("quotes").item(0);
Node textNode = document.createElement("text");
textNode.setTextContent(quote.text);
Node quoteNode = document.createElement("quote");
quoteNode.appendChild(textNode);
root.appendChild(quoteNode);
}
And we're green.
As I was looking at the code, I figured there might be a better way to get the root element.
There is...
public void newQuote(Quote quote) {
Node root = document.getDocumentElement();
Node textNode = document.createElement("text");
textNode.setTextContent(quote.text);
Node quoteNode = document.createElement("quote");
quoteNode.appendChild(textNode);
root.appendChild(quoteNode);
}
Still green. Adding more rigor...
public void testShouldWriteXmlWhenGivenNewQuote() throws Exception {
String text = "Program to an interface, not an implementation.";
String isbn = "0201633612";
String title = "Design Patterns";
String firstName = "Gang";
String lastName = "of Four";
String url = "http://c2.com/cgi/wiki?GangOfFour";
Collection
It's not a perfect test, but it's the simplest test (that I can come up with)
that will drive me to where I want to go.
This code passes the test:
public void newQuote(Quote quote) {
Node root = document.getDocumentElement();
Node quoteNode = document.createElement("quote");
Node textNode = document.createElement("text");
textNode.setTextContent(quote.text);
quoteNode.appendChild(textNode);
Node sourceNode = document.createElement("source");
Attr sourceIsbn = document.createAttribute("isbn");
sourceIsbn.setValue(quote.source.isbn);
sourceNode.getAttributes().setNamedItem(sourceIsbn);
sourceNode.setTextContent(quote.source.title);
quoteNode.appendChild(sourceNode);
for (Person author : quote.authors) {
Attr authorUrl = document.createAttribute("url");
authorUrl.setValue(author.url);
Node authorNode = document.createElement("author");
authorNode.getAttributes().setNamedItem(authorUrl);
Node authorFirst = document.createElement("first");
authorFirst.setTextContent(author.firstName);
authorNode.appendChild(authorFirst);
Node authorLast = document.createElement("last");
authorLast.setTextContent(author.lastName);
authorNode.appendChild(authorLast);
quoteNode.appendChild(authorNode);
}
root.appendChild(quoteNode);
}
Very straightforward. I'm feeling good about this right now.
I'm going to add more tests to handle some different variations of authors, quoters, and sources.
I won't bore you with those unless something interesting comes up.
Well, that didn't take long. Something interesting came up. Here's the new test...
public void testShouldWriteXmlWhenGivenNewQuoteWithPageNumber() throws Exception {
String text = "The major problems of our work are not so much <i>technological</i> as <i>sociological</i> in nature.";
String isbn = "0932633439";
String title = "Peopleware: Productive Projects and Teams";
String page = "4";
String firstName1 = "Tom";
String lastName1 = "DeMarco";
String url1 = "http://www.systemsguild.com/GuildSite/TDM/Tom_DeMarco.html";
String firstName2 = "Timothy";
String lastName2 = "Lister";
String url2 = "http://www.cutter.com/consultants/tlbio.html";
Collection<Person> authors = new ArrayList<Person>(2);
authors.add(new Person(firstName1, lastName1, url1));
authors.add(new Person(firstName2, lastName2, url2));
Quote quote = new Quote(text, new Source(title, page, isbn), authors, null);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("stub.xml");
assertEquals(0, document.getElementsByTagName("quote").getLength());
Manager manager = new XmlQuoteManager(document);
manager.newQuote(quote);
assertEquals(1, document.getElementsByTagName("quote").getLength());
String textContent = documentToText(document);
assertTrue(-1 != textContent.indexOf("<text>" + text + "</text>"));
assertTrue(-1 != textContent.indexOf("<source isbn=\""+ isbn + "\" page=\"" + page + "\">" + title + "</source>"));
assertTrue(-1 != textContent.indexOf("<author url=\""+ url1 + "\"><first>" + firstName1 + "</first><last>" + lastName1 + "</last></author>"));
assertTrue(-1 != textContent.indexOf("<author url=\""+ url2 + "\"><first>" + firstName2 + "</first><last>" + lastName2 + "</last></author>"));
}
I expected this to fail because the code doesn't handle pages.
But it failed for a different reason.
The HTML in the quote got escaped and failed at the first assertTrue!
I'm going to comment out all the other asserts while I resolve this issue...
|