Skip to content

Commit

Permalink
Factored out load_required method, added test for doc tree updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jlorieau committed Aug 15, 2019
1 parent 485cde5 commit 0acc136
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 24 deletions.
58 changes: 41 additions & 17 deletions src/disseminate/document/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def load_subdocuments(self):
recursive=True)

# Clear the subdocuments ordered dict and add new entries. Old entries
# will automatically be delete if the subdocument no longer holds a
# will automatically be deleted if the subdocument no longer holds a
# reference to it.
self.subdocuments.clear()

Expand All @@ -416,19 +416,55 @@ def load_subdocuments(self):
# ordered dict
if src_filepath in root_dict:
subdoc = root_dict[src_filepath]
subdoc.load() # Make sure the subdocument is loaded

if self.src_filepath not in subdoc.subdocuments:
self.subdocuments[src_filepath] = subdoc
continue

# The document could not be found, at this point. Create it.

# Create the document and add it to the subdocuments ordered
# dict.
subdoc = Document(src_filepath=src_filepath,
parent_context=self.context)
self.subdocuments[src_filepath] = subdoc

def load_required(self):
"""Evaluate whether a load is required.
Returns
-------
load_required : bool
True, if a load is required.
False if a load isn't required.
"""
# Reload the document if:
# 1. The document hasn't been successfully loaded.
if not self._succesfully_loaded:
return True

# 2. The body attribute hasn't been set yet.
body_attr = settings.body_attr
if self.context.get(body_attr, None) is None:
return True

# 3. The mtime for the file is now later than the one stored in the
# context--i.e. the user saved the file.
src_mtime = self.src_filepath.stat().st_mtime
last_mtime = self.mtime
if last_mtime is None or src_mtime > last_mtime:
return True

# 4. This is a subdocument whose context has a parent_context, and the
# parent_context has been updated
parent_context = self.context.parent_context
parent_mtime = (parent_context.get('mtime')
if parent_context is not None else None)
if parent_mtime is not None and parent_mtime > last_mtime:
return True

return False

def load(self, reload=False):
"""Load or reload the document into the context.
Expand All @@ -442,26 +478,14 @@ def load(self, reload=False):
msg = "The source document '{}' must exist."
raise DocumentError(msg.format(self.src_filepath))

stat = self.src_filepath.stat()
time = stat.st_mtime
last_mtime = self.mtime

# Update the context, if:
# 1. The document hasn't been successfully loaded.
# 2. The body attribute hasn't been set yet.
# 3. The mtime for the file is now later than the one stored in the
# context--i.e. the user saved the file.
# 4. A reload is forced
body_attr = settings.body_attr
if (not self._succesfully_loaded or
self.context.get(body_attr, None) is None or
last_mtime is None or time > last_mtime or
reload):
# Load document if a load is required or forced
if self.load_required() or reload:

# The document hasn't been loaded yet. Reset the flat
self._succesfully_loaded = False

# Check to make sure the file is reasonable
stat = self.src_filepath.stat()
filesize = stat.st_size
if filesize > settings.document_max_size:
msg = ("The source document '{}' has a file size ({} kB) "
Expand Down
4 changes: 2 additions & 2 deletions tests/document/processors/test_process_context_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def test_process_context_header_precedence(doctree):
---
""")
for doc in (doc1, doc2, doc3):
doc.load(reload=True)
doc.load()

assert doc1.context['template'] == 'test'
assert doc1.context['inactive_tags'] == {'chapter'}
Expand All @@ -139,7 +139,7 @@ def test_process_context_header_precedence(doctree):
---
""")
for doc in (doc1, doc2, doc3):
doc.load(reload=True)
doc.load()

assert doc1.context['inactive_tags'] == {'title', 'chapter'} # appended
assert doc2.context['inactive_tags'] == {'title', 'chapter'}
Expand Down
8 changes: 3 additions & 5 deletions tests/document/test_document_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,9 @@ def test_document_tree_updates_document_labels(tmpdir, wait):
doc_list = doc.documents_list()
assert len(doc_list) == 3

# There should be 3 labels, one for each document. However, they haven't
# been registered yet since this is done when we get labels. The only
# document whose ast has been reloaded and the labels have been reset is
# document 1 so there should only be collected labels for this document.
assert len(label_manager.collected_labels) == 1
# There should be 3 labels, one for each document. Changing the root
# document reloads all documents
assert len(label_manager.collected_labels) == 3

assert doc_list[0].src_filepath == src_filepath1
assert doc_list[1].src_filepath == src_filepath3
Expand Down
40 changes: 40 additions & 0 deletions tests/document/test_document_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,46 @@ def test_document_tree(tmpdir):
assert target_filepath.is_file()


def test_document_tree_load_required(doctree):
"""Test the load_required method for document trees."""
# Load the 3 documents from the doctree
doc1, doc2, doc3 = doctree.documents_list()

# 1. Take an attribute, and it should match the default context
for doc in (doc1, doc2, doc3):
assert (doc.context['inactive_tags'] ==
settings.default_context['inactive_tags'])

# 2. Now add a template with a context.txt
src_path = doc1.src_filepath.parent
template_filepath = src_path / 'test.html'
context_filepath = src_path / 'context.txt'

template_filepath.write_text("""
<html>
</html>
""")
context_filepath.write_text("""
inactive_tags: chapter
""")
doc1.src_filepath.write_text("""
---
template: test
include:
test2.dm
test3.dm
---
""")

# Load the root document should reload the child documents
doc1.load()

assert doc1.context['template'] == 'test'
assert doc1.context['inactive_tags'] == {'chapter'}
assert doc2.context['inactive_tags'] == {'chapter'}
assert doc3.context['inactive_tags'] == {'chapter'}


def test_document_garbage_collection(tmpdir):
"""Test the garbage collection of document trees."""

Expand Down

0 comments on commit 0acc136

Please sign in to comment.