from glob import glob import os from pathlib import Path import pickle from .. import load, loads import pytest DATADIR = os.path.join(os.path.dirname(__file__), 'data') def load_data(path): """Load data from python file""" ns = {} # type: ignore # read_bytes() and compile hackery to avoid encoding issues (e.g. see 05_tags) exec(compile(Path(path).read_bytes(), path, 'exec'), ns) return ns['data'] def value_from_data_key(node, key): """ Helper function for check_data. Get value from Orgnode by key. """ if key == 'tags_inher': return node.tags elif key == 'children_heading': return [c.heading for c in node.children] elif key in ('parent_heading', 'previous_same_level_heading', 'next_same_level_heading', ): othernode = getattr(node, key.rsplit('_', 1)[0]) if othernode and not othernode.is_root(): return othernode.heading else: return else: return getattr(node, key) def data_path(dataname, ext): return os.path.join(DATADIR, '{0}.{1}'.format(dataname, ext)) def get_datanames(): for oname in sorted(glob(os.path.join(DATADIR, '*.org'))): yield os.path.splitext(os.path.basename(oname))[0] @pytest.mark.parametrize('dataname', get_datanames()) def test_data(dataname): """ Compare parsed data from 'data/*.org' and its correct answer 'data/*.py' """ oname = data_path(dataname, "org") data = load_data(data_path(dataname, "py")) root = load(oname) for (i, (node, kwds)) in enumerate(zip(root[1:], data)): for key in kwds: val = value_from_data_key(node, key) assert kwds[key] == val, 'check value of {0}-th node of key "{1}" from "{2}".\n\nParsed:\n{3}\n\nReal:\n{4}'.format(i, key, dataname, val, kwds[key]) assert type(kwds[key]) == type(val), 'check type of {0}-th node of key "{1}" from "{2}".\n\nParsed:\n{3}\n\nReal:\n{4}'.format(i, key, dataname, type(val), type(kwds[key])) assert root.env.filename == oname @pytest.mark.parametrize('dataname', get_datanames()) def test_picklable(dataname): oname = data_path(dataname, "org") root = load(oname) pickle.dumps(root) def test_iter_node(): root = loads(""" * H1 ** H2 *** H3 * H4 ** H5 """) node = root[1] assert node.heading == 'H1' by_iter = [n.heading for n in node] assert by_iter == ['H1', 'H2', 'H3'] def test_commented_headings_do_not_appear_as_children(): root = loads("""\ * H1 #** H2 ** H3 #* H4 #** H5 * H6 """) assert root.linenumber == 1 top_level = root.children assert len(top_level) == 2 h1 = top_level[0] assert h1.heading == "H1" assert h1.get_body() == "#** H2" assert h1.linenumber == 1 [h3] = h1.children assert h3.heading == "H3" assert h3.get_body() == "#* H4\n#** H5" assert h3.linenumber == 3 h6 = top_level[1] assert h6.heading == "H6" assert len(h6.children) == 0 assert h6.linenumber == 6 def test_commented_clock_entries_are_ignored_by_node_clock(): root = loads("""\ * Heading # * Floss # SCHEDULED: <2019-06-22 Sat 08:30 .+1w> # :LOGBOOK: # CLOCK: [2019-06-04 Tue 16:00]--[2019-06-04 Tue 17:00] => 1:00 # :END: """) [node] = root.children[0] assert node.heading == "Heading" assert node.clock == [] def test_commented_scheduled_marker_is_ignored_by_node_scheduled(): root = loads("""\ * Heading # SCHEDULED: <2019-06-22 Sat 08:30 .+1w> """) [node] = root.children[0] assert node.heading == "Heading" assert node.scheduled.start is None def test_commented_property_is_ignored_by_node_get_property(): root = loads("""\ * Heading # :PROPERTIES: # :PROPER-TEA: backup # :END: """) [node] = root.children[0] assert node.heading == "Heading" assert node.get_property("PROPER-TEA") is None