aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/orgparse/tests
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/orgparse/tests')
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.org17
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.py33
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.org29
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.py73
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.org31
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.py44
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.org5
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.py13
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.org7
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.py11
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.org9
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.py23
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/data/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/test_data.py154
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/test_date.py42
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/test_hugedata.py30
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/test_misc.py299
-rw-r--r--.venv/lib/python3.12/site-packages/orgparse/tests/test_rich.py89
19 files changed, 909 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/__init__.py b/.venv/lib/python3.12/site-packages/orgparse/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.org
new file mode 100644
index 00000000..3a373334
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.org
@@ -0,0 +1,17 @@
+#+STARTUP: hidestars
+#+SEQ_TODO: TODO1 TODO2 TODO3 TODO4
+
+* TODO1 Heading 0 :TAG1:
+** TODO2 Heading 1 :TAG2:
+*** TODO3 Heading 2 :TAG3:
+**** TODO4 Heading 3 :TAG4:
+ CLOSED: [2010-08-06 Fri 21:45]
+** Heading 4
+** Heading 5
+* Heading 6 :TAG2:
+** Heading 7 :TAG2:
+*** Heading 8
+***** Heading 9 :TAG3:TAG4:
+**** Heading 10 :TAG1:
+** Heading 11
+* Heading 12
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.py
new file mode 100644
index 00000000..c0b23d1d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/00_simple.py
@@ -0,0 +1,33 @@
+from typing import Any, Dict, Set
+
+
+def nodedict(i, level, todo=None, shallow_tags=set([]), tags=set([])) -> Dict[str, Any]:
+ return dict(
+ heading="Heading {0}".format(i),
+ level=level,
+ todo=todo,
+ shallow_tags=shallow_tags,
+ tags=tags,
+ )
+
+
+def tags(nums) -> Set[str]:
+ return set(map('TAG{0}'.format, nums))
+
+
+data = [
+ nodedict(i, *vals) for (i, vals) in enumerate([ # type: ignore[misc]
+ [1, 'TODO1', tags([1]) , tags(range(1, 2))],
+ [2, 'TODO2', tags([2]) , tags(range(1, 3))],
+ [3, 'TODO3', tags([3]) , tags(range(1, 4))],
+ [4, 'TODO4', tags([4]) , tags(range(1, 5))],
+ [2, None , tags([]) , tags([1]) ],
+ [2, None , tags([]) , tags([1]) ],
+ [1, None , tags([2]) , tags([2]) ],
+ [2, None , tags([2]) , tags([2]) ],
+ [3, None , tags([]) , tags([2]) ],
+ [5, None , tags([3, 4]), tags([2, 3, 4]) ],
+ [4, None , tags([1]) , tags([1, 2]) ],
+ [2, None , tags([]) , tags([2]) ],
+ [1],
+ ])]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.org
new file mode 100644
index 00000000..99e202b5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.org
@@ -0,0 +1,29 @@
+#+STARTUP: hidestars
+* DONE [#A] A node with a lot of attributes
+ SCHEDULED: <2010-08-06 Fri> DEADLINE: <2010-08-10 Tue> CLOSED: [2010-08-08 Sun 18:00]
+ CLOCK: [2010-08-08 Sun 17:40]--[2010-08-08 Sun 17:50] => 0:10
+ CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] => 0:30
+ :PROPERTIES:
+ :Effort: 1:10
+ :END:
+ - <2010-08-16 Mon> DateList
+ - <2010-08-07 Sat>--<2010-08-08 Sun>
+ - <2010-08-09 Mon 00:30>--<2010-08-10 Tue 13:20> RangeList
+ - <2019-08-10 Sat 16:30-17:30> TimeRange
+* A node without any attributed
+* DONE [#A] A node with a lot of attributes
+ SCHEDULED: <2010-08-06 Fri> DEADLINE: <2010-08-10 Tue> CLOSED: [2010-08-08 Sun 18:00]
+ CLOCK: [2010-08-08 Sun 17:40]--[2010-08-08 Sun 17:50] => 0:10
+ CLOCK: [2010-08-08 Sun 17:00]--[2010-08-08 Sun 17:30] => 0:30
+ :PROPERTIES:
+ :Effort: 1:10
+ :END:
+ - <2010-08-16 Mon> DateList
+ - <2010-08-07 Sat>--<2010-08-08 Sun>
+ - <2010-08-09 Mon 00:30>--<2010-08-10 Tue 13:20> RangeList
+ - <2019-08-10 Sat 16:30-17:30> TimeRange
+* range in deadline
+DEADLINE: <2019-09-06 Fri 10:00--11:20>
+ body
+* node with a second line but no date
+body
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.py
new file mode 100644
index 00000000..d4555dea
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/01_attributes.py
@@ -0,0 +1,73 @@
+from typing import Dict, Any
+
+from orgparse.date import (
+ OrgDate, OrgDateScheduled, OrgDateDeadline, OrgDateClosed,
+ OrgDateClock,
+)
+
+Raw = Dict[str, Any]
+
+node1: Raw = dict(
+ heading="A node with a lot of attributes",
+ priority='A',
+ scheduled=OrgDateScheduled((2010, 8, 6)),
+ deadline=OrgDateDeadline((2010, 8, 10)),
+ closed=OrgDateClosed((2010, 8, 8, 18, 0)),
+ clock=[
+ OrgDateClock((2010, 8, 8, 17, 40), (2010, 8, 8, 17, 50), 10),
+ OrgDateClock((2010, 8, 8, 17, 00), (2010, 8, 8, 17, 30), 30),
+ ],
+ properties=dict(Effort=70),
+ datelist=[OrgDate((2010, 8, 16))],
+ rangelist=[
+ OrgDate((2010, 8, 7), (2010, 8, 8)),
+ OrgDate((2010, 8, 9, 0, 30), (2010, 8, 10, 13, 20)),
+ OrgDate((2019, 8, 10, 16, 30, 0), (2019, 8, 10, 17, 30, 0)),
+ ],
+ body="""\
+ - <2010-08-16 Mon> DateList
+ - <2010-08-07 Sat>--<2010-08-08 Sun>
+ - <2010-08-09 Mon 00:30>--<2010-08-10 Tue 13:20> RangeList
+ - <2019-08-10 Sat 16:30-17:30> TimeRange"""
+)
+
+node2: Raw = dict(
+ heading="A node without any attributed",
+ priority=None,
+ scheduled=OrgDateScheduled(None),
+ deadline=OrgDateDeadline(None),
+ closed=OrgDateClosed(None),
+ clock=[],
+ properties={},
+ datelist=[],
+ rangelist=[],
+ body="",
+)
+
+node3: Raw = dict(
+ heading="range in deadline",
+ priority=None,
+ scheduled=OrgDateScheduled(None),
+ deadline=OrgDateDeadline((2019, 9, 6, 10, 0), (2019, 9, 6, 11, 20)),
+ closed=OrgDateClosed(None),
+ clock=[],
+ properties={},
+ datelist=[],
+ rangelist=[],
+ body=" body",
+)
+
+node4: Raw = dict(
+ heading="node with a second line but no date",
+ priority=None,
+ scheduled=OrgDateScheduled(None),
+ deadline=OrgDateDeadline(None),
+ closed=OrgDateClosed(None),
+ clock=[],
+ properties={},
+ datelist=[],
+ rangelist=[],
+ body="body",
+)
+
+data = [node1, node2, node1, node3, node4]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.org
new file mode 100644
index 00000000..5f4b6fb2
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.org
@@ -0,0 +1,31 @@
+* G0-H1
+
+* G1-H1
+** G1-H2
+*** G1-H3
+
+* G2-H1
+*** G2-H2
+** G2-H3
+
+* G3-H1
+**** G3-H2
+** G3-H3
+
+* G4-H1
+**** G4-H2
+*** G4-H3
+** G4-H4
+
+* G5-H1
+** G5-H2
+*** G5-H3
+** G5-H4
+
+* G6-H1
+** G6-H2
+**** G6-H3
+*** G6-H4
+** G6-H5
+
+* G7-H1
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.py
new file mode 100644
index 00000000..80a8e779
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/02_tree_struct.py
@@ -0,0 +1,44 @@
+from typing import Any, Dict
+
+
+def nodedict(parent, children=[], previous=None, next=None) -> Dict[str, Any]:
+ return dict(parent_heading=parent,
+ children_heading=children,
+ previous_same_level_heading=previous,
+ next_same_level_heading=next)
+
+
+data = [nodedict(*args) for args in [
+ # G0
+ (None, [], None, 'G1-H1'),
+ # G1
+ (None, ['G1-H2'], 'G0-H1', 'G2-H1'),
+ ('G1-H1', ['G1-H3']),
+ ('G1-H2',),
+ # G2
+ (None, ['G2-H2', 'G2-H3'], 'G1-H1', 'G3-H1'),
+ ('G2-H1',),
+ ('G2-H1',),
+ # G3
+ (None, ['G3-H2', 'G3-H3'], 'G2-H1', 'G4-H1'),
+ ('G3-H1',),
+ ('G3-H1',),
+ # G4
+ (None, ['G4-H2', 'G4-H3', 'G4-H4'], 'G3-H1', 'G5-H1'),
+ ('G4-H1',),
+ ('G4-H1',),
+ ('G4-H1',),
+ # G5
+ (None, ['G5-H2', 'G5-H4'], 'G4-H1', 'G6-H1'),
+ ('G5-H1', ['G5-H3'], None, 'G5-H4'),
+ ('G5-H2',),
+ ('G5-H1', [], 'G5-H2'),
+ # G6
+ (None, ['G6-H2', 'G6-H5'], 'G5-H1', 'G7-H1'),
+ ('G6-H1', ['G6-H3', 'G6-H4'], None, 'G6-H5'),
+ ('G6-H2',),
+ ('G6-H2',),
+ ('G6-H1', [], 'G6-H2'),
+ # G7
+ (None, [], 'G6-H1'),
+]]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.org
new file mode 100644
index 00000000..9e9c79b5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.org
@@ -0,0 +1,5 @@
+* TODO Pay the rent
+ DEADLINE: <2005-10-01 Sat +1m>
+ - State "DONE" from "TODO" [2005-09-01 Thu 16:10]
+ - State "DONE" from "TODO" [2005-08-01 Mon 19:44]
+ - State "DONE" from "TODO" [2005-07-01 Fri 17:27]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.py
new file mode 100644
index 00000000..18cfe121
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/03_repeated_tasks.py
@@ -0,0 +1,13 @@
+from orgparse.date import OrgDateRepeatedTask, OrgDateDeadline
+
+
+data = [dict(
+ heading='Pay the rent',
+ todo='TODO',
+ deadline=OrgDateDeadline((2005, 10, 1)),
+ repeated_tasks=[
+ OrgDateRepeatedTask((2005, 9, 1, 16, 10, 0), 'TODO', 'DONE'),
+ OrgDateRepeatedTask((2005, 8, 1, 19, 44, 0), 'TODO', 'DONE'),
+ OrgDateRepeatedTask((2005, 7, 1, 17, 27, 0), 'TODO', 'DONE'),
+ ]
+)]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.org
new file mode 100644
index 00000000..e89ec262
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.org
@@ -0,0 +1,7 @@
+* LOGBOOK drawer test
+ :LOGBOOK:
+ CLOCK: [2012-10-26 Fri 16:01]
+ CLOCK: [2012-10-26 Fri 14:50]--[2012-10-26 Fri 15:00] => 0:10
+ CLOCK: [2012-10-26 Fri 14:30]--[2012-10-26 Fri 14:40] => 0:10
+ CLOCK: [2012-10-26 Fri 14:10]--[2012-10-26 Fri 14:20] => 0:10
+ :END:
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.py
new file mode 100644
index 00000000..457c5fa1
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/04_logbook.py
@@ -0,0 +1,11 @@
+from orgparse.date import OrgDateClock
+
+data = [dict(
+ heading='LOGBOOK drawer test',
+ clock=[
+ OrgDateClock((2012, 10, 26, 16, 1)),
+ OrgDateClock((2012, 10, 26, 14, 50), (2012, 10, 26, 15, 00)),
+ OrgDateClock((2012, 10, 26, 14, 30), (2012, 10, 26, 14, 40)),
+ OrgDateClock((2012, 10, 26, 14, 10), (2012, 10, 26, 14, 20)),
+ ]
+)]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.org b/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.org
new file mode 100644
index 00000000..651d7e09
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.org
@@ -0,0 +1,9 @@
+* Node 0 :tag:
+* Node 1 :@tag:
+* Node 2 :tag1:tag2:
+* Node 3 :_:
+* Node 4 :@:
+* Node 5 :@_:
+* Node 6 :_tag_:
+* Heading: :with:colon: :tag:
+* unicode :ёж:tag:háček:
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.py
new file mode 100644
index 00000000..52aee638
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/05_tags.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+def nodedict(i, tags):
+ return dict(
+ heading="Node {0}".format(i),
+ tags=set(tags),
+ )
+
+
+data = [
+ nodedict(i, *vals) for (i, vals) in enumerate([
+ [["tag"]],
+ [["@tag"]],
+ [["tag1", "tag2"]],
+ [["_"]],
+ [["@"]],
+ [["@_"]],
+ [["_tag_"]],
+ ])] + [
+ dict(heading='Heading: :with:colon:', tags=set(["tag"])),
+ ] + [
+ dict(heading='unicode', tags=set(['ёж', 'tag', 'háček'])),
+ ]
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/data/__init__.py b/.venv/lib/python3.12/site-packages/orgparse/tests/data/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/data/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/test_data.py b/.venv/lib/python3.12/site-packages/orgparse/tests/test_data.py
new file mode 100644
index 00000000..f315878e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/test_data.py
@@ -0,0 +1,154 @@
+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
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/test_date.py b/.venv/lib/python3.12/site-packages/orgparse/tests/test_date.py
new file mode 100644
index 00000000..0f39575b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/test_date.py
@@ -0,0 +1,42 @@
+from orgparse.date import OrgDate, OrgDateScheduled, OrgDateDeadline, OrgDateClock, OrgDateClosed
+import datetime
+
+
+def test_date_as_string() -> None:
+
+ testdate = datetime.date(2021, 9, 3)
+ testdate2 = datetime.date(2021, 9, 5)
+ testdatetime = datetime.datetime(2021, 9, 3, 16, 19, 13)
+ testdatetime2 = datetime.datetime(2021, 9, 3, 17, 0, 1)
+ testdatetime_nextday = datetime.datetime(2021, 9, 4, 0, 2, 1)
+
+ assert str(OrgDate(testdate)) == "<2021-09-03 Fri>"
+ assert str(OrgDate(testdatetime)) == "<2021-09-03 Fri 16:19>"
+ assert str(OrgDate(testdate, active=False)) == "[2021-09-03 Fri]"
+ assert str(OrgDate(testdatetime, active=False)) == "[2021-09-03 Fri 16:19]"
+
+ assert str(OrgDate(testdate, testdate2)) == "<2021-09-03 Fri>--<2021-09-05 Sun>"
+ assert str(OrgDate(testdate, testdate2)) == "<2021-09-03 Fri>--<2021-09-05 Sun>"
+ assert str(OrgDate(testdatetime, testdatetime2)) == "<2021-09-03 Fri 16:19--17:00>"
+ assert str(OrgDate(testdate, testdate2, active=False)) == "[2021-09-03 Fri]--[2021-09-05 Sun]"
+ assert str(OrgDate(testdate, testdate2, active=False)) == "[2021-09-03 Fri]--[2021-09-05 Sun]"
+ assert str(OrgDate(testdatetime, testdatetime2, active=False)) == "[2021-09-03 Fri 16:19--17:00]"
+
+ assert str(OrgDateScheduled(testdate)) == "<2021-09-03 Fri>"
+ assert str(OrgDateScheduled(testdatetime)) == "<2021-09-03 Fri 16:19>"
+ assert str(OrgDateDeadline(testdate)) == "<2021-09-03 Fri>"
+ assert str(OrgDateDeadline(testdatetime)) == "<2021-09-03 Fri 16:19>"
+ assert str(OrgDateClosed(testdate)) == "[2021-09-03 Fri]"
+ assert str(OrgDateClosed(testdatetime)) == "[2021-09-03 Fri 16:19]"
+
+ assert str(OrgDateClock(testdatetime, testdatetime2)) == "[2021-09-03 Fri 16:19]--[2021-09-03 Fri 17:00]"
+ assert str(OrgDateClock(testdatetime, testdatetime_nextday)) == "[2021-09-03 Fri 16:19]--[2021-09-04 Sat 00:02]"
+ assert str(OrgDateClock(testdatetime)) == "[2021-09-03 Fri 16:19]"
+
+
+def test_date_as_datetime() -> None:
+ testdate = (2021, 9, 3)
+ testdatetime = (2021, 9, 3, 16, 19, 13)
+
+ assert OrgDate._as_datetime(datetime.date(*testdate)) == datetime.datetime(*testdate, 0, 0, 0)
+ assert OrgDate._as_datetime(datetime.datetime(*testdatetime)) == datetime.datetime(*testdatetime) \ No newline at end of file
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/test_hugedata.py b/.venv/lib/python3.12/site-packages/orgparse/tests/test_hugedata.py
new file mode 100644
index 00000000..f7248ca7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/test_hugedata.py
@@ -0,0 +1,30 @@
+import pickle
+
+from .. import loadi
+
+
+def generate_org_lines(num_top_nodes, depth=3, nodes_per_level=1, _level=1):
+ if depth == 0:
+ return
+ for i in range(num_top_nodes):
+ yield ("*" * _level) + ' {0}-th heading of level {1}'.format(i, _level)
+ for child in generate_org_lines(
+ nodes_per_level, depth - 1, nodes_per_level, _level + 1):
+ yield child
+
+
+def num_generate_org_lines(num_top_nodes, depth=3, nodes_per_level=1):
+ if depth == 0:
+ return 0
+ return num_top_nodes * (
+ 1 + num_generate_org_lines(
+ nodes_per_level, depth - 1, nodes_per_level))
+
+
+def test_picklable() -> None:
+ num = 1000
+ depth = 3
+ nodes_per_level = 1
+ root = loadi(generate_org_lines(num, depth, nodes_per_level))
+ assert sum(1 for _ in root) == num_generate_org_lines(num, depth, nodes_per_level) + 1
+ pickle.dumps(root) # should not fail
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/test_misc.py b/.venv/lib/python3.12/site-packages/orgparse/tests/test_misc.py
new file mode 100644
index 00000000..4cd73e4c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/test_misc.py
@@ -0,0 +1,299 @@
+from .. import load, loads
+from ..node import OrgEnv
+from orgparse.date import OrgDate
+
+
+def test_empty_heading() -> None:
+ root = loads('''
+* TODO :sometag:
+ has no heading but still a todo?
+ it's a bit unclear, but seems to be highligted by emacs..
+''')
+ [h] = root.children
+ assert h.todo == 'TODO'
+ assert h.heading == ''
+ assert h.tags == {'sometag'}
+
+
+def test_root() -> None:
+ root = loads('''
+#+STARTUP: hidestars
+Whatever
+# comment
+* heading 1
+ '''.strip())
+ assert len(root.children) == 1
+ # todo not sure if should strip special comments??
+ assert root.body.endswith('Whatever\n# comment')
+ assert root.heading == ''
+
+
+def test_stars():
+ # https://github.com/karlicoss/orgparse/issues/7#issuecomment-533732660
+ root = loads("""
+* Heading with text (A)
+
+The following line is not a heading, because it begins with a
+star but has no spaces afterward, just a newline:
+
+*
+
+** Subheading with text (A1)
+
+*this_is_just*
+
+ *some_bold_text*
+
+This subheading is a child of (A).
+
+The next heading has no text, but it does have a space after
+the star, so it's a heading:
+
+*
+
+This text is under the "anonymous" heading above, which would be (B).
+
+** Subheading with text (B1)
+
+This subheading is a child of the "anonymous" heading (B), not of heading (A).
+ """)
+ [h1, h2] = root.children
+ assert h1.heading == 'Heading with text (A)'
+ assert h2.heading == ''
+
+
+def test_parse_custom_todo_keys():
+ todo_keys = ['TODO', 'CUSTOM1', 'ANOTHER_KEYWORD']
+ done_keys = ['DONE', 'A']
+ filename = '<string>' # default for loads
+ content = """
+* TODO Heading with a default todo keyword
+
+* DONE Heading with a default done keyword
+
+* CUSTOM1 Heading with a custom todo keyword
+
+* ANOTHER_KEYWORD Heading with a long custom todo keyword
+
+* A Heading with a short custom done keyword
+ """
+
+ env = OrgEnv(todos=todo_keys, dones=done_keys, filename=filename)
+ root = loads(content, env=env)
+
+ assert root.env.all_todo_keys == ['TODO', 'CUSTOM1',
+ 'ANOTHER_KEYWORD', 'DONE', 'A']
+ assert len(root.children) == 5
+ assert root.children[0].todo == 'TODO'
+ assert root.children[1].todo == 'DONE'
+ assert root.children[2].todo == 'CUSTOM1'
+ assert root.children[3].todo == 'ANOTHER_KEYWORD'
+ assert root.children[4].todo == 'A'
+
+
+def test_add_custom_todo_keys():
+ todo_keys = ['CUSTOM_TODO']
+ done_keys = ['CUSTOM_DONE']
+ filename = '<string>' # default for loads
+ content = """#+TODO: COMMENT_TODO | COMMENT_DONE
+ """
+
+ env = OrgEnv(filename=filename)
+ env.add_todo_keys(todos=todo_keys, dones=done_keys)
+
+ # check that only the custom keys are know before parsing
+ assert env.all_todo_keys == ['CUSTOM_TODO', 'CUSTOM_DONE']
+
+ # after parsing, all keys are set
+ root = loads(content, filename, env)
+ assert root.env.all_todo_keys == ['CUSTOM_TODO', 'COMMENT_TODO',
+ 'CUSTOM_DONE', 'COMMENT_DONE']
+
+def test_get_file_property() -> None:
+ content = """#+TITLE: Test: title
+ * Node 1
+ test 1
+ * Node 2
+ test 2
+ """
+
+ # after parsing, all keys are set
+ root = loads(content)
+ assert root.get_file_property('Nosuchproperty') is None
+ assert root.get_file_property_list('TITLE') == ['Test: title']
+ # also it's case insensitive
+ assert root.get_file_property('title') == 'Test: title'
+ assert root.get_file_property_list('Nosuchproperty') == []
+
+
+def test_get_file_property_multivalued() -> None:
+ content = """ #+TITLE: Test
+ #+OTHER: Test title
+ #+title: alternate title
+
+ * Node 1
+ test 1
+ * Node 2
+ test 2
+ """
+
+ # after parsing, all keys are set
+ root = loads(content)
+ import pytest
+
+ assert root.get_file_property_list('TITLE') == ['Test', 'alternate title']
+ with pytest.raises(RuntimeError):
+ # raises because there are multiple of them
+ root.get_file_property('TITLE')
+
+
+def test_filetags_are_tags() -> None:
+ content = '''
+#+FILETAGS: :f1:f2:
+
+* heading :h1:
+** child :f2:
+ '''.strip()
+ root = loads(content)
+ # breakpoint()
+ assert root.tags == {'f1', 'f2'}
+ child = root.children[0].children[0]
+ assert child.tags == {'f1', 'f2', 'h1'}
+
+
+def test_load_filelike() -> None:
+ import io
+ stream = io.StringIO('''
+* heading1
+* heading 2
+''')
+ root = load(stream)
+ assert len(root.children) == 2
+ assert root.env.filename == '<file-like>'
+
+
+def test_level_0_properties() -> None:
+ content = '''
+foo bar
+
+:PROPERTIES:
+:PROP-FOO: Bar
+:PROP-BAR: Bar bar
+:END:
+
+* heading :h1:
+:PROPERTIES:
+:HEADING-PROP: foo
+:END:
+** child :f2:
+ '''.strip()
+ root = loads(content)
+ assert root.get_property('PROP-FOO') == 'Bar'
+ assert root.get_property('PROP-BAR') == 'Bar bar'
+ assert root.get_property('PROP-INVALID') is None
+ assert root.get_property('HEADING-PROP') is None
+ assert root.children[0].get_property('HEADING-PROP') == 'foo'
+
+
+def test_level_0_timestamps() -> None:
+ content = '''
+foo bar
+
+ - <2010-08-16 Mon> DateList
+ - <2010-08-07 Sat>--<2010-08-08 Sun>
+ - <2010-08-09 Mon 00:30>--<2010-08-10 Tue 13:20> RangeList
+ - <2019-08-10 Sat 16:30-17:30> TimeRange"
+
+* heading :h1:
+** child :f2:
+ '''.strip()
+ root = loads(content)
+ assert root.datelist == [OrgDate((2010, 8, 16))]
+ assert root.rangelist == [
+ OrgDate((2010, 8, 7), (2010, 8, 8)),
+ OrgDate((2010, 8, 9, 0, 30), (2010, 8, 10, 13, 20)),
+ OrgDate((2019, 8, 10, 16, 30, 0), (2019, 8, 10, 17, 30, 0)),
+ ]
+
+def test_date_with_cookies() -> None:
+ testcases = [
+ ('<2010-06-21 Mon +1y>',
+ "OrgDate((2010, 6, 21), None, True, ('+', 1, 'y'))"),
+ ('<2005-10-01 Sat +1m>',
+ "OrgDate((2005, 10, 1), None, True, ('+', 1, 'm'))"),
+ ('<2005-10-01 Sat +1m -3d>',
+ "OrgDate((2005, 10, 1), None, True, ('+', 1, 'm'), ('-', 3, 'd'))"),
+ ('<2005-10-01 Sat -3d>',
+ "OrgDate((2005, 10, 1), None, True, None, ('-', 3, 'd'))"),
+ ('<2008-02-10 Sun ++1w>',
+ "OrgDate((2008, 2, 10), None, True, ('++', 1, 'w'))"),
+ ('<2008-02-08 Fri 20:00 ++1d>',
+ "OrgDate((2008, 2, 8, 20, 0, 0), None, True, ('++', 1, 'd'))"),
+ ('<2019-04-05 Fri 08:00 .+1h>',
+ "OrgDate((2019, 4, 5, 8, 0, 0), None, True, ('.+', 1, 'h'))"),
+ ('[2019-04-05 Fri 08:00 .+1h]',
+ "OrgDate((2019, 4, 5, 8, 0, 0), None, False, ('.+', 1, 'h'))"),
+ ('<2007-05-16 Wed 12:30 +1w>',
+ "OrgDate((2007, 5, 16, 12, 30, 0), None, True, ('+', 1, 'w'))"),
+ ]
+ for (input, expected) in testcases:
+ root = loads(input)
+ output = root[0].datelist[0]
+ assert str(output) == input
+ assert repr(output) == expected
+ testcases = [
+ ('<2006-11-02 Thu 20:00-22:00 +1w>',
+ "OrgDate((2006, 11, 2, 20, 0, 0), (2006, 11, 2, 22, 0, 0), True, ('+', 1, 'w'))"),
+ ('<2006-11-02 Thu 20:00--22:00 +1w>',
+ "OrgDate((2006, 11, 2, 20, 0, 0), (2006, 11, 2, 22, 0, 0), True, ('+', 1, 'w'))"),
+ ]
+ for (input, expected) in testcases:
+ root = loads(input)
+ output = root[0].rangelist[0]
+ assert str(output) == "<2006-11-02 Thu 20:00--22:00 +1w>"
+ assert repr(output) == expected
+ # DEADLINE and SCHEDULED
+ testcases2 = [
+ ('* TODO Pay the rent\nDEADLINE: <2005-10-01 Sat +1m>',
+ "<2005-10-01 Sat +1m>",
+ "OrgDateDeadline((2005, 10, 1), None, True, ('+', 1, 'm'))"),
+ ('* TODO Pay the rent\nDEADLINE: <2005-10-01 Sat +1m -3d>',
+ "<2005-10-01 Sat +1m -3d>",
+ "OrgDateDeadline((2005, 10, 1), None, True, ('+', 1, 'm'), ('-', 3, 'd'))"),
+ ('* TODO Pay the rent\nDEADLINE: <2005-10-01 Sat -3d>',
+ "<2005-10-01 Sat -3d>",
+ "OrgDateDeadline((2005, 10, 1), None, True, None, ('-', 3, 'd'))"),
+ ('* TODO Pay the rent\nDEADLINE: <2005-10-01 Sat ++1m>',
+ "<2005-10-01 Sat ++1m>",
+ "OrgDateDeadline((2005, 10, 1), None, True, ('++', 1, 'm'))"),
+ ('* TODO Pay the rent\nDEADLINE: <2005-10-01 Sat .+1m>',
+ "<2005-10-01 Sat .+1m>",
+ "OrgDateDeadline((2005, 10, 1), None, True, ('.+', 1, 'm'))"),
+ ]
+ for (input, expected_str, expected_repr) in testcases2:
+ root = loads(input)
+ output = root[1].deadline
+ assert str(output) == expected_str
+ assert repr(output) == expected_repr
+ testcases2 = [
+ ('* TODO Pay the rent\nSCHEDULED: <2005-10-01 Sat +1m>',
+ "<2005-10-01 Sat +1m>",
+ "OrgDateScheduled((2005, 10, 1), None, True, ('+', 1, 'm'))"),
+ ('* TODO Pay the rent\nSCHEDULED: <2005-10-01 Sat +1m -3d>',
+ "<2005-10-01 Sat +1m -3d>",
+ "OrgDateScheduled((2005, 10, 1), None, True, ('+', 1, 'm'), ('-', 3, 'd'))"),
+ ('* TODO Pay the rent\nSCHEDULED: <2005-10-01 Sat -3d>',
+ "<2005-10-01 Sat -3d>",
+ "OrgDateScheduled((2005, 10, 1), None, True, None, ('-', 3, 'd'))"),
+ ('* TODO Pay the rent\nSCHEDULED: <2005-10-01 Sat ++1m>',
+ "<2005-10-01 Sat ++1m>",
+ "OrgDateScheduled((2005, 10, 1), None, True, ('++', 1, 'm'))"),
+ ('* TODO Pay the rent\nSCHEDULED: <2005-10-01 Sat .+1m>',
+ "<2005-10-01 Sat .+1m>",
+ "OrgDateScheduled((2005, 10, 1), None, True, ('.+', 1, 'm'))"),
+ ]
+ for (input, expected_str, expected_repr) in testcases2:
+ root = loads(input)
+ output = root[1].scheduled
+ assert str(output) == expected_str
+ assert repr(output) == expected_repr
diff --git a/.venv/lib/python3.12/site-packages/orgparse/tests/test_rich.py b/.venv/lib/python3.12/site-packages/orgparse/tests/test_rich.py
new file mode 100644
index 00000000..7fb911b9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/orgparse/tests/test_rich.py
@@ -0,0 +1,89 @@
+'''
+Tests for rich formatting: tables etc.
+'''
+from .. import load, loads
+from ..extra import Table
+
+import pytest
+
+
+def test_table() -> None:
+ root = loads('''
+| | | |
+| | "heading" | |
+| | | |
+|-------+-----------+-----|
+| reiwf | fef | |
+|-------+-----------+-----|
+|-------+-----------+-----|
+| aba | caba | 123 |
+| yeah | | X |
+
+ |------------------------+-------|
+ | when | count |
+ | datetime | int |
+ |------------------------+-------|
+ | | -1 |
+ | [2020-11-05 Thu 23:44] | |
+ | [2020-11-06 Fri 01:00] | 1 |
+ |------------------------+-------|
+
+some irrelevant text
+
+| simple |
+|--------|
+| value1 |
+| value2 |
+ ''')
+
+ [gap1, t1, gap2, t2, gap3, t3, gap4] = root.body_rich
+
+ t1 = Table(root._lines[1:10])
+ t2 = Table(root._lines[11:19])
+ t3 = Table(root._lines[22:26])
+
+ assert ilen(t1.blocks) == 4
+ assert list(t1.blocks)[2] == []
+ assert ilen(t1.rows) == 6
+
+ with pytest.raises(RuntimeError):
+ list(t1.as_dicts) # not sure what should it be
+
+ assert ilen(t2.blocks) == 2
+ assert ilen(t2.rows) == 5
+ assert list(t2.rows)[3] == ['[2020-11-05 Thu 23:44]', '']
+
+
+ assert ilen(t3.blocks) == 2
+ assert list(t3.rows) == [['simple'], ['value1'], ['value2']]
+ assert t3.as_dicts.columns == ['simple']
+ assert list(t3.as_dicts) == [{'simple': 'value1'}, {'simple': 'value2'}]
+
+
+def test_table_2() -> None:
+ root = loads('''
+* item
+
+#+tblname: something
+| date | value | comment |
+|----------------------+-------+-------------------------------|
+| 14.04.17 | 11 | aaaa |
+| May 26 2017 08:00 | 12 | what + about + pluses? |
+| May 26 09:00 - 10:00 | 13 | time is |
+
+ some comment
+
+#+BEGIN_SRC python :var fname="plot.png" :var table=something :results file
+fig.savefig(fname)
+return fname
+#+END_SRC
+
+#+RESULTS:
+[[file:plot.png]]
+''')
+ [_, t, _] = root.children[0].body_rich
+ assert ilen(t.as_dicts) == 3
+
+
+def ilen(x) -> int:
+ return len(list(x))