"""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()