"""Tests for micronian.page http://www.decafbad.com mailto:l.m.orchard@pobox.com Share and Enjoy """ import sys, isodate from tzinfo_examples import UTC from datetime import datetime from random import random from StringIO import StringIO from lxml import etree import unittest from micronian.page import Page, NS class TestCase(unittest.TestCase): # TODO: Stop using page.doc object directly? def setUp(self): """Create some reusable objects for tests.""" self.p1 = Page("TestPage", """

This is a sample node added to the doc.

Here's some more.

Nothing to see here

Isn't this fun?

""") def tearDown(self): """ """ pass def testCreate(self): """Test result of Page creation.""" p = Page("TestPage") self.assert_(p.doc is not None, "Document should've been created.") body = p.doc.xpath('//xhtml:body', NS) body_cnt = len(body) self.assertEqual(body_cnt, 1, "Page should have 1 HTML body node, found %s." % body_cnt) body_fc = body[0][0] self.assert_('div' in body_fc.tag, "First child of body should be a div, found %s." % \ body_fc.tag) self.assert_(body_fc.get('id') is not None, "Initial page div should have an ID.") def testMetaTitle(self): """Try manipulating the document title.""" self.assertEqual(self.p1['title'], "TestPage", "Page title should initially equal None.") orig_title = "TestTitleName" self.p1['title'] = orig_title result_title = self.p1['title'] self.assertEqual(orig_title, result_title, "'%s' should equal '%s'" % (result_title, orig_title)) title_nodes = \ self.p1.doc.xpath("/xhtml:html/xhtml:head/xhtml:title", NS) self.assert_(len(title_nodes) == 1, "There should be 1 title node, found %s" % len(title_nodes)) title_node = title_nodes[0] self.assertEqual(title_node.text, orig_title) def testMetaModified(self): """Try setting and getting a modification timestamp.""" self.assertEqual(self.p1['modified'], None, "Page modification should initially equal None.") # Come up with a time vaguely based on the present moment. from tzinfo_examples import Eastern now = datetime.now(tz=Eastern).replace(microsecond=0) now_str = now.isoformat('T') self.p1['modified'] = now self.assertEqual(self.p1['modified'], now, "Modified datetime should equal %s, found %s." % \ (now, self.p1['modified'])) modified_nodes = \ self.p1.doc.xpath("/xhtml:html/xhtml:head/" + \ "xhtml:meta[@name='DCTERMS.modified']", NS) self.assert_(len(modified_nodes) == 1, "Should have found one for modified.") modified_text = modified_nodes[0].get('content') self.assertEqual(modified_text, now_str, "Expected %s for modified, found %s." % \ (now_str, modified_text)) def testCreateWithInvalid(self): """Test result of Page creation with invalid source.""" def do_create(self): p = Page("BrokenPage", 'test") self.assert_(node is not None, "Should have gotten a node.") self.assert_(node.tag == 'foo', "Node tag should have been 'foo', was '%s'" % node.tag) def testNodeFromFile(self): """Try out the private _node() method with a file.""" node = self.p1._node(StringIO("test")) self.assert_(node is not None, "Should have gotten a node.") self.assert_(node.tag == 'bar', "Node tag should have been 'bar', was '%s'" % node.tag) def testNodeFromNode(self): """Try out the private _node() method with a node.""" src_node = etree.parse(StringIO("test")).getroot() node = self.p1._node(src_node) self.assert_(node is not None, "Should have gotten a node.") self.assert_(node.tag == 'baz', "Node tag should have been 'baz', was '%s'" % node.tag) def testAppendNode(self): """Try appending a node to the page body.""" self.p1.append("""

This is a sample node added to the doc.

Here's some more.

Isn't this fun?

""") divs = self.p1.doc.xpath('/xhtml:html/xhtml:body/xhtml:div', NS) self.assert_(len(divs)==2, "There should be 2
, found %s" % len(divs)) paras = divs[0].xpath('/xhtml:html/xhtml:body/xhtml:div/xhtml:p', NS) self.assert_(len(paras)==7, "There should be 7

, found %s" % len(paras)) def testReplace(self): """Try replacing an existing node.""" self.p1.replace("""

Excuse me while I cut in.

""" % NS['xhtml'], "//xhtml:p[@id='p3']") def do_find_missing(x): node = self.p1.get("//xhtml:p[@id='p3']") self.assertRaises(KeyError, do_find_missing, "Replaced node should no longer be found.") ids = [ x.get('id') for x in self.p1.doc.xpath('//xhtml:p', NS) ] cmp_ids = [ 'p1', 'p2', 'test1', 'p4' ] self.assertEqual(ids, cmp_ids, "ID order %s expected, found %s" % (cmp_ids, ids)) def testInsertBefore(self): """Try inserting a node before another node.""" self.p1.insertBefore("""

Excuse me while I cut in.

""" % NS['xhtml'], "//xhtml:p[@id='p3']") node = self.p1.get("//xhtml:p[@id='test1']") self.failIf(node is None, "New node should have been found.") ids = [ x.get('id') for x in self.p1.doc.xpath('//xhtml:p', NS) ] cmp_ids = [ 'p1', 'p2', 'test1', 'p3', 'p4' ] self.assertEqual(ids, cmp_ids, "ID order %s expected, found %s" % (cmp_ids, ids)) def testDeleteNode(self): """Try deleting a node.""" self.p1.delete("/xhtml:div/xhtml:p[@id='p3']") paras = self.p1.doc.xpath('//xhtml:p', NS) self.assert_(len(paras) == 3, "Should have found 3

, found %s" % len(paras)) def testDeleteMissingNode(self): """Try deleting a non-existent node.""" p1 = self.p1 def do_delete(self): p1.delete("//xhtml:p[@id='does_not_exist']") self.assertRaises(KeyError, do_delete, "Deletion of nonexistent node should raise KeyError") def testIDCreation(self): """Double check that IDs are auto-created for structural elements.""" parent = etree.XML("""

""") for t in [ 'foo', 'bar', 'baz', 'xyzzy' ]: node = etree.XML("
%s
" % t) parent.append(node) self.p1.append(parent) divs = self.p1.doc.xpath("//xhtml:div[@id='test1']", NS) self.assert_(len(divs) > 0, "There should be divs added") for div in divs: div_id = div.get('id') self.assert_(div_id is not None and div_id != '', '
ID should be defined.') def testToString(self): """Test out serializing a page to string form.""" # TODO: Do some fine-grained comparisons between P1 and P2 src = u""" TestPage2

This is a sample node added.

Here's some more.

Nothing to see here

Isn't this fun?

""" p1 = Page("PageOne", src) p1_src = p1.toString() p2 = Page("PageOne", p1_src) p2_src = p2.toString() self.assert_(p1_src != "", "Page 1 source shouldn't be blank") self.assert_(p2_src != "", "Page 2 source shouldn't be blank") paras = p2.doc.xpath("//xhtml:p", NS) self.assert_(len(paras) == 4, "Should've found 4

, found %s instead." % len(paras)) self.assertEqual(p1_src, p2_src, "Pages sources should match. Should be:\n%s\nFound:\n%s"%\ (p1_src, p2_src)) if __name__ == '__main__': unittest.main()