Compare commits

..

No commits in common. "develop" and "dev/render-as-dom" have entirely different histories.

17 changed files with 324 additions and 1454 deletions

View File

@ -1,53 +0,0 @@
name: Testing
# run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: [push]
jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip
- run: pip install -e .
- run: pip install pytest
- run: pytest
mypy:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip
- run: pip install -e .
- run: pip install mypy
- run: mypy org_rw --check-untyped-defs
style-formatting:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip
- run: pip install -e .
- run: pip install black
- run: black --check .
style-sorted-imports:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: apt-get update && apt-get install -y python3-pip
- run: pip install -e .
- run: pip install isort
- run: isort --profile black --check .
stability-extra-test:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- run: apt-get update && apt-get install -y git-core python3-pip
- run: pip install -e .
- run: bash extra-tests/check_all.sh

3
.gitignore vendored
View File

@ -139,6 +139,3 @@ dmypy.json
# Cython debug symbols
cython_debug/
# Files for PyPI publishing
README.md

View File

@ -1,6 +1,3 @@
from typing import List, Optional, Union
class DrawerNode:
def __init__(self):
self.children = []
@ -41,12 +38,11 @@ class ListGroupNode:
self.children.append(child)
def get_raw(self):
return "\n".join([c.get_raw() for c in self.children])
return '\n'.join([c.get_raw() for c in self.children])
def __repr__(self):
return "<List: {}>".format(len(self.children))
class TableNode:
def __init__(self):
self.children = []
@ -57,24 +53,21 @@ class TableNode:
def __repr__(self):
return "<Table: {}>".format(len(self.children))
class TableSeparatorRow:
def __init__(self, orig=None):
self.orig = orig
class TableRow:
def __init__(self, cells, orig=None):
self.cells = cells
self.orig = orig
class Text:
def __init__(self, content):
self.content = content
def get_raw(self):
return "".join(self.content.get_raw())
return ''.join(self.content.get_raw())
class ListItem:
@ -99,7 +92,7 @@ class CodeBlock(BlockNode):
def __init__(self, header, subtype, arguments):
super().__init__()
self.header = header
self.lines: Optional[List] = None
self.lines = None
self.subtype = subtype
self.arguments = arguments
@ -107,26 +100,6 @@ class CodeBlock(BlockNode):
self.lines = lines
def __repr__(self):
return "<Code: {}>".format(len(self.lines or []))
DomNode = Union[
DrawerNode,
PropertyNode,
ListGroupNode,
TableNode,
TableSeparatorRow,
TableRow,
Text,
ListItem,
BlockNode,
]
ContainerDomNode = Union[
DrawerNode,
ListGroupNode,
TableNode,
BlockNode,
]
return "<Code: {}>".format(len(self.lines))
from .utils import get_raw_contents

File diff suppressed because it is too large Load Diff

View File

View File

@ -1,18 +0,0 @@
import re
from typing import List, TypedDict
class HeadlineDict(TypedDict):
linenum: int
orig: re.Match
title: str
contents: List
children: List
keywords: List
properties: List
logbook: List
structural: List
delimiters: List
results: List # TODO: Move to each specific code block?
list_items: List
table_rows: List

View File

@ -1,19 +1,9 @@
import uuid
from .org_rw import (
Bold,
Code,
Headline,
Italic,
Line,
ListItem,
RawLine,
Strike,
Text,
Underlined,
Verbatim,
dump_contents,
)
from .org_rw import (Bold, Code, Headline, Italic, Line, RawLine, ListItem, Strike, Text,
Underlined, Verbatim)
from .org_rw import dump_contents
def get_hl_raw_contents(doc: Headline) -> str:

View File

@ -1,11 +0,0 @@
#!/bin/sh
set -eu
cd "`dirname $0`"
cd ..
set -x
isort --profile black .
black .

View File

@ -5,8 +5,6 @@ set -eu
cd "`dirname $0`"
cd ..
pandoc README.org -o README.md # PyPI doesn't accept Org files
python setup.py sdist
twine upload --verbose dist/*

View File

@ -2,7 +2,7 @@ from setuptools import setup
setup(
name="org-rw",
version="0.0.2",
version="0.0.1.dev1",
description="Library to de/serialize org-files and manipulate them.",
author="kenkeiras",
author_email="kenkeiras@codigoparallevar.com",

View File

@ -21,10 +21,3 @@
This is a [[https://codigoparallevar.com/4][[tricky web link]]] followed up with some text.
This is [[[https://codigoparallevar.com/5][another tricky web link]]] followed up with some text.
* Implicit links
:PROPERTIES:
:ID: 03-markup-implicit-links
:CREATED: [2020-01-01 Wed 01:01]
:END:
This is an implicit web link: https://codigoparallevar.com/implicit.

View File

@ -9,7 +9,6 @@
:CREATED: [2020-01-01 Wed 01:01]
:END:
#+NAME: first-code-name
#+BEGIN_SRC shell :results verbatim
echo "This is a test"
echo "with two lines"

View File

@ -1,22 +0,0 @@
#+TITLE: 12-Headlines with skip levels
#+DESCRIPTION: Simple org file to test Headlines with skip levels
#+TODO: TODO(t) PAUSED(p) | DONE(d)
* Level 1
:PROPERTIES:
:ID: 12-headlines-with-skip-levels
:CREATED: [2020-01-01 Wed 01:01]
:END:
*** Level 3
*** Level 3-2
* Level 1-2
** Level 2
**** Level 4
*** Level3

View File

@ -1,13 +0,0 @@
#+TITLE: 13-Tags
#+DESCRIPTION: Simple org file to test tags
#+FILETAGS: :filetag:
* Level 1 :h1tag:
:PROPERTIES:
:ID: 13-tags
:CREATED: [2020-01-01 Wed 01:01]
:END:
** Level2 :h2tag:
* Level 1-1 :otherh1tag:
** Level2 :otherh2tag:

View File

@ -1,23 +1,14 @@
import logging
import os
import unittest
from datetime import date
from datetime import datetime as DT
from utils.assertions import (
BOLD,
CODE,
HL,
ITALIC,
SPAN,
STRIKE,
UNDERLINED,
VERBATIM,
WEB_LINK,
Doc,
Tokens,
)
from org_rw import MarkerToken, MarkerType, Timestamp, dumps, load, loads, dom
import org_rw
from org_rw import MarkerToken, MarkerType, Timestamp, dom, dumps, load, loads
from utils.assertions import (BOLD, CODE, HL, ITALIC, SPAN, STRIKE, UNDERLINED,
VERBATIM, WEB_LINK, Doc, Tokens)
DIR = os.path.dirname(os.path.abspath(__file__))
@ -211,7 +202,7 @@ class TestSerde(unittest.TestCase):
doc = load(f)
links = list(doc.get_links())
self.assertEqual(len(links), 8)
self.assertEqual(len(links), 7)
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
self.assertEqual(links[0].description, "web link")
@ -233,9 +224,6 @@ class TestSerde(unittest.TestCase):
self.assertEqual(links[6].value, "https://codigoparallevar.com/5")
self.assertEqual(links[6].description, "another tricky web link")
self.assertEqual(links[7].value, "https://codigoparallevar.com/implicit")
self.assertEqual(links[7].description, "https://codigoparallevar.com/implicit")
ex = Doc(
props=[
("TITLE", "03-Links"),
@ -292,35 +280,17 @@ class TestSerde(unittest.TestCase):
SPAN("\n"),
SPAN(
" This is a ",
WEB_LINK(
"[tricky web link]\u200b",
"https://codigoparallevar.com/4",
),
WEB_LINK("[tricky web link]\u200b", "https://codigoparallevar.com/4"),
" followed up with some text.\n",
),
SPAN("\n"),
SPAN(
" This is [",
WEB_LINK(
"another tricky web link",
"https://codigoparallevar.com/5",
),
WEB_LINK("another tricky web link", "https://codigoparallevar.com/5"),
"] followed up with some text.\n",
),
],
),
HL(
"Implicit links",
props=[
("ID", "03-markup-implicit-links"),
("CREATED", DT(2020, 1, 1, 1, 1)),
],
content=[
SPAN(
" This is an implicit web link: https://codigoparallevar.com/implicit.\n",
),
],
),
)
),
)
@ -331,7 +301,7 @@ class TestSerde(unittest.TestCase):
doc = load(f)
links = list(doc.get_links())
self.assertEqual(len(links), 8)
self.assertEqual(len(links), 7)
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
self.assertEqual(links[0].description, "web link")
links[0].value = "https://codigoparallevar.com/1-updated"
@ -367,9 +337,6 @@ class TestSerde(unittest.TestCase):
links[6].value = "https://codigoparallevar.com/5-updated"
links[6].description = "another tricky web link #5 with update"
self.assertEqual(links[7].value, "https://codigoparallevar.com/implicit")
self.assertEqual(links[7].description, "https://codigoparallevar.com/implicit")
ex = Doc(
props=[
("TITLE", "03-Links"),
@ -449,19 +416,7 @@ class TestSerde(unittest.TestCase):
"] followed up with some text.\n",
),
],
),
HL(
"Implicit links",
props=[
("ID", "03-markup-implicit-links"),
("CREATED", DT(2020, 1, 1, 1, 1)),
],
content=[
SPAN(
" This is an implicit web link: https://codigoparallevar.com/implicit.\n",
),
],
),
)
),
)
@ -480,22 +435,18 @@ class TestSerde(unittest.TestCase):
snippets = list(doc.get_code_snippets())
self.assertEqual(len(snippets), 3)
self.assertEqual(snippets[0].name, "first-code-name")
self.assertEqual(snippets[0].language, "shell")
self.assertEqual(
snippets[0].content,
'echo "This is a test"\n'
+ 'echo "with two lines"\n'
+ "exit 0 # Exit successfully",
)
self.assertEqual(snippets[0].arguments.split(), [":results", "verbatim"])
self.assertEqual(snippets[0].arguments.split(), ['shell', ':results', 'verbatim'])
self.assertEqual(
snippets[0].result,
"This is a test\n" + "with two lines",
)
self.assertEqual(snippets[1].name, None)
self.assertEqual(snippets[1].language, "shell")
self.assertEqual(
snippets[1].content,
'echo "This is another test"\n'
@ -506,14 +457,12 @@ class TestSerde(unittest.TestCase):
snippets[1].result, "This is another test\n" + "with two lines too"
)
self.assertEqual(snippets[2].name, None)
self.assertEqual(snippets[2].language, "c")
self.assertEqual(
snippets[2].content,
"/* This code has to be escaped to\n"
+ " * avoid confusion with new headlines.\n"
+ " */\n"
+ "main(){}",
'/* This code has to be escaped to\n'
+ ' * avoid confusion with new headlines.\n'
+ ' */\n'
+ 'main(){}',
)
def test_mimic_write_file_05(self):
@ -551,7 +500,7 @@ class TestSerde(unittest.TestCase):
hl_schedule_range = hl.children[1]
self.assertEqual(
hl_schedule_range.scheduled.time,
Timestamp(True, 2020, 12, 15, "Mar", 0, 5, "++1w"),
Timestamp(True, 2020, 12, 15, "Mar", 0, 5, '++1w')
)
self.assertEqual(
hl_schedule_range.scheduled.end_time,
@ -559,7 +508,7 @@ class TestSerde(unittest.TestCase):
)
self.assertEqual(
hl_schedule_range.scheduled.repetition,
"++1w",
'++1w',
)
def test_update_info_file_05(self):
@ -612,8 +561,7 @@ class TestSerde(unittest.TestCase):
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
"markup",
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
".",
"\n",
".", "\n"
],
)
@ -647,24 +595,12 @@ class TestSerde(unittest.TestCase):
print(lists4)
self.assertEqual(len(lists4), 2)
self.assertEqual(
lists4[0][0].content,
["This is a list item...", "\n that spans multiple lines", "\n"],
)
self.assertEqual(lists4[0][0].content, ["This is a list item...", "\n that spans multiple lines", "\n"])
self.assertEqual(lists4[0][0].bullet, "-")
self.assertEqual(
lists4[0][1].content,
[
"This is another list item...",
"\n that has content on multiple lines",
"\n",
],
)
self.assertEqual(lists4[0][1].content, ["This is another list item...", "\n that has content on multiple lines", "\n"])
self.assertEqual(lists4[0][1].bullet, "-")
self.assertEqual(
lists4[1][0].content, ["This is another", "\n multiline list", "\n"]
)
self.assertEqual(lists4[1][0].content, ["This is another", "\n multiline list", "\n"])
self.assertEqual(lists4[1][0].bullet, "-")
def test_org_roam_07(self):
@ -708,22 +644,20 @@ class TestSerde(unittest.TestCase):
""".strip(),
)
def test_markup_file_09(self):
with open(os.path.join(DIR, "09-markup-on-headline.org")) as f:
doc = load(f)
hl = doc.getTopHeadlines()[0]
print(hl.title)
self.assertEqual(
hl.title.contents,
[
"Headline ",
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
"with",
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
" markup",
],
)
self.assertEqual(hl.title.contents, [
'Headline ',
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
'with',
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
' markup',
])
def test_mimic_write_file_10(self):
with open(os.path.join(DIR, "10-tables.org")) as f:
@ -744,9 +678,9 @@ class TestSerde(unittest.TestCase):
print(first_table[0])
self.assertEqual(len(first_table[0].cells), 3)
self.assertEqual(first_table[0].cells[0].strip(), "Header1")
self.assertEqual(first_table[0].cells[1].strip(), "Header2")
self.assertEqual(first_table[0].cells[2].strip(), "Header3")
self.assertEqual(first_table[0].cells[0].strip(), 'Header1')
self.assertEqual(first_table[0].cells[1].strip(), 'Header2')
self.assertEqual(first_table[0].cells[2].strip(), 'Header3')
hl = hl.children[0]
@ -756,9 +690,9 @@ class TestSerde(unittest.TestCase):
print(first_table[0])
self.assertEqual(len(first_table[0].cells), 3)
self.assertEqual(first_table[0].cells[0].strip(), "Header1")
self.assertEqual(first_table[0].cells[1].strip(), "Header2")
self.assertEqual(first_table[0].cells[2].strip(), "Header3")
self.assertEqual(first_table[0].cells[0].strip(), 'Header1')
self.assertEqual(first_table[0].cells[1].strip(), 'Header2')
self.assertEqual(first_table[0].cells[2].strip(), 'Header3')
def test_tables_html_file_10(self):
with open(os.path.join(DIR, "10-tables.org")) as f:
@ -768,26 +702,27 @@ class TestSerde(unittest.TestCase):
tree = hl.as_dom()
non_props = [
item for item in tree if not isinstance(item, dom.PropertyDrawerNode)
item
for item in tree
if not isinstance(item, dom.PropertyDrawerNode)
]
self.assertTrue(
isinstance(non_props[0], dom.Text)
and isinstance(non_props[1], dom.TableNode)
and isinstance(non_props[2], dom.Text),
"Expected <Text><Table><Text>",
)
self.assertTrue(isinstance(non_props[0], dom.Text)
and isinstance(non_props[1], dom.TableNode)
and isinstance(non_props[2], dom.Text),
'Expected <Text><Table><Text>')
hl = hl.children[0]
tree = hl.as_dom()
non_props = [
item
for item in tree
if not (
isinstance(item, dom.PropertyDrawerNode) or isinstance(item, dom.Text)
)
if not (isinstance(item, dom.PropertyDrawerNode)
or isinstance(item, dom.Text))
]
print_tree(non_props)
self.assertTrue(len(non_props) == 1, "Expected <List>, with only (1) element")
self.assertTrue(len(non_props) == 1,
'Expected <List>, with only (1) element')
def test_nested_lists_html_file_11(self):
with open(os.path.join(DIR, "11-nested-lists.org")) as f:
@ -797,232 +732,30 @@ class TestSerde(unittest.TestCase):
tree = hl.as_dom()
non_props = [
item for item in tree if not isinstance(item, dom.PropertyDrawerNode)
item
for item in tree
if not isinstance(item, dom.PropertyDrawerNode)
]
print_tree(non_props)
self.assertTrue(
(len(non_props) == 1) and (isinstance(non_props[0], dom.ListGroupNode)),
"Expected only <List> as top level",
)
self.assertTrue((len(non_props) == 1) and (isinstance(non_props[0], dom.ListGroupNode)),
'Expected only <List> as top level')
dom_list = non_props[0]
children = dom_list.children
self.assertTrue(
len(children) == 5, "Expected 5 items inside <List>, 3 texts and 2 sublists"
)
self.assertTrue(len(children) == 5, 'Expected 5 items inside <List>, 3 texts and 2 sublists')
# Assert texts
self.assertEqual(children[0].content, ["1"])
self.assertEqual(children[2].content, ["2"])
self.assertEqual(
children[4].content[0], "3"
) # Might be ['3', '\n'] but shouldn't be a breaking change
self.assertEqual(children[0].content, ['1'])
self.assertEqual(children[2].content, ['2'])
self.assertEqual(children[4].content[0], '3') # Might be ['3', '\n'] but shouldn't be a breaking change
# Assert lists
self.assertTrue(
isinstance(children[1], dom.ListGroupNode), 'Expected sublist inside "1"'
)
self.assertEqual(children[1].children[0].content, ["1.1"])
self.assertEqual(children[1].children[1].content, ["1.2"])
self.assertTrue(
isinstance(children[3], dom.ListGroupNode), 'Expected sublist inside "2"'
)
self.assertEqual(children[3].children[0].content, ["2.1"])
self.assertEqual(children[3].children[1].content, ["2.2"])
def test_mimic_write_file_12(self):
with open(os.path.join(DIR, "12-headlines-with-skip-levels.org")) as f:
orig = f.read()
doc = loads(orig)
self.assertEqual(dumps(doc), orig)
def test_add_todo_keywords_programatically(self):
orig = """* NEW_TODO_STATE First entry
* NEW_DONE_STATE Second entry"""
doc = loads(
orig, environment={"org-todo-keywords": "NEW_TODO_STATE | NEW_DONE_STATE"}
)
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[1].is_todo, False)
self.assertEqual(doc.headlines[1].is_done, True)
self.assertEqual(dumps(doc), orig)
def test_add_todo_keywords_in_file(self):
orig = """#+TODO: NEW_TODO_STATE | NEW_DONE_STATE
* NEW_TODO_STATE First entry
* NEW_DONE_STATE Second entry"""
doc = loads(
orig, environment={"org-todo-keywords": "NEW_TODO_STATE | NEW_DONE_STATE"}
)
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[1].is_todo, False)
self.assertEqual(doc.headlines[1].is_done, True)
self.assertEqual(dumps(doc), orig)
def test_mimic_write_file_13(self):
with open(os.path.join(DIR, "13-tags.org")) as f:
orig = f.read()
doc = loads(orig)
self.assertEqual(dumps(doc), orig)
def test_tag_property_read_13(self):
with open(os.path.join(DIR, "13-tags.org")) as f:
orig = f.read()
doc = loads(orig)
self.assertEqual(doc.tags, ["filetag"])
h1_1, h1_2 = doc.getTopHeadlines()
self.assertEqual(sorted(h1_1.tags), ["filetag", "h1tag"])
self.assertEqual(sorted(h1_2.tags), ["filetag", "otherh1tag"])
h1_1_h2 = h1_1.children[0]
self.assertEqual(sorted(h1_1_h2.tags), ["filetag", "h1tag", "h2tag"])
h1_2_h2 = h1_2.children[0]
self.assertEqual(sorted(h1_2_h2.tags), ["filetag", "otherh1tag", "otherh2tag"])
def test_shallow_tag_property_read_13(self):
with open(os.path.join(DIR, "13-tags.org")) as f:
orig = f.read()
doc = loads(orig)
self.assertEqual(doc.shallow_tags, ["filetag"])
h1_1, h1_2 = doc.getTopHeadlines()
self.assertEqual(sorted(h1_1.shallow_tags), ["h1tag"])
self.assertEqual(sorted(h1_2.shallow_tags), ["otherh1tag"])
h1_1_h2 = h1_1.children[0]
self.assertEqual(sorted(h1_1_h2.shallow_tags), ["h2tag"])
h1_2_h2 = h1_2.children[0]
self.assertEqual(sorted(h1_2_h2.shallow_tags), ["otherh2tag"])
def test_exclude_tags_from_inheritance_property_read_13(self):
with open(os.path.join(DIR, "13-tags.org")) as f:
orig = f.read()
doc = loads(
orig,
{
"org-tags-exclude-from-inheritance": ("h1tag", "otherh2tag"),
},
)
self.assertEqual(doc.tags, ["filetag"])
h1_1, h1_2 = doc.getTopHeadlines()
self.assertEqual(sorted(h1_1.tags), ["filetag", "h1tag"])
self.assertEqual(sorted(h1_2.tags), ["filetag", "otherh1tag"])
h1_1_h2 = h1_1.children[0]
self.assertEqual(sorted(h1_1_h2.tags), ["filetag", "h2tag"])
h1_2_h2 = h1_2.children[0]
self.assertEqual(sorted(h1_2_h2.tags), ["filetag", "otherh1tag", "otherh2tag"])
def test_select_tags_to_inheritance_property_read_13(self):
with open(os.path.join(DIR, "13-tags.org")) as f:
orig = f.read()
doc = loads(
orig,
{
"org-tags-exclude-from-inheritance": ("h1tag", "otherh2tag"),
"org-use-tag-inheritance": ("h1tag",),
},
)
self.assertEqual(doc.tags, ["filetag"])
h1_1, h1_2 = doc.getTopHeadlines()
self.assertEqual(sorted(h1_1.tags), ["h1tag"])
self.assertEqual(sorted(h1_2.tags), ["otherh1tag"])
h1_1_h2 = h1_1.children[0]
self.assertEqual(sorted(h1_1_h2.tags), ["h1tag", "h2tag"])
h1_2_h2 = h1_2.children[0]
self.assertEqual(sorted(h1_2_h2.tags), ["otherh2tag"])
def test_update_headline_from_none_to_todo(self):
orig = "* First entry"
doc = loads(orig)
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state, None)
doc.headlines[0].state = "TODO"
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state["name"], "TODO")
self.assertEqual(dumps(doc), "* TODO First entry")
def test_update_headline_from_none_to_done(self):
orig = "* First entry"
doc = loads(orig)
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state, None)
doc.headlines[0].state = org_rw.HeadlineState(name="DONE")
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, True)
self.assertEqual(doc.headlines[0].state["name"], "DONE")
self.assertEqual(dumps(doc), "* DONE First entry")
def test_update_headline_from_todo_to_none(self):
orig = "* TODO First entry"
doc = loads(orig)
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state["name"], "TODO")
doc.headlines[0].state = None
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state, None)
self.assertEqual(dumps(doc), "* First entry")
def test_update_headline_from_todo_to_done(self):
orig = "* TODO First entry"
doc = loads(orig)
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state["name"], "TODO")
doc.headlines[0].state = "DONE"
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, True)
self.assertEqual(doc.headlines[0].state["name"], "DONE")
self.assertEqual(dumps(doc), "* DONE First entry")
def test_update_headline_from_done_to_todo(self):
orig = "* DONE First entry"
doc = loads(orig)
self.assertEqual(doc.headlines[0].is_todo, False)
self.assertEqual(doc.headlines[0].is_done, True)
self.assertEqual(doc.headlines[0].state["name"], "DONE")
doc.headlines[0].state = org_rw.HeadlineState(name="TODO")
self.assertEqual(doc.headlines[0].is_todo, True)
self.assertEqual(doc.headlines[0].is_done, False)
self.assertEqual(doc.headlines[0].state["name"], "TODO")
self.assertEqual(dumps(doc), "* TODO First entry")
self.assertTrue(isinstance(children[1], dom.ListGroupNode), 'Expected sublist inside "1"')
self.assertEqual(children[1].children[0].content, ['1.1'])
self.assertEqual(children[1].children[1].content, ['1.2'])
self.assertTrue(isinstance(children[3], dom.ListGroupNode), 'Expected sublist inside "2"')
self.assertEqual(children[3].children[0].content, ['2.1'])
self.assertEqual(children[3].children[1].content, ['2.2'])
def print_tree(tree, indentation=0, headline=None):
@ -1042,10 +775,6 @@ def print_element(element, indentation, headline):
if isinstance(element, org_rw.Link):
print(" " * indentation * 2, "Link:", element.get_raw())
elif isinstance(element, str):
print(
" " * indentation * 2,
"Str[" + element.replace("\n", "<NL>") + "]",
type(element),
)
print(" " * indentation * 2, "Str[" + element.replace('\n', '<NL>') + "]", type(element))
else:
print_tree(element, indentation, headline)

View File

@ -1,86 +0,0 @@
"""Test the Timestamp object."""
from datetime import date, datetime
import pytest
from org_rw import Timestamp
def test_init_with_datetime() -> None:
datetime_obj: datetime = datetime(2024, 7, 20, 15, 45)
ts: Timestamp = Timestamp(active=True, datetime_=datetime_obj)
assert ts.active is True
assert ts._year == 2024
assert ts._month == 7
assert ts._day == 20
assert ts.hour == 15
assert ts.minute == 45
assert ts.dow is None
assert ts.repetition is None
def test_init_with_date() -> None:
date_obj: date = date(2024, 7, 20)
ts: Timestamp = Timestamp(active=True, datetime_=date_obj)
assert ts.active is True
assert ts._year == 2024
assert ts._month == 7
assert ts._day == 20
assert ts.hour is None
assert ts.minute is None
assert ts.dow is None
assert ts.repetition is None
def test_init_with_year_month_day() -> None:
ts: Timestamp = Timestamp(
active=True,
year=2024,
month=7,
day=20,
hour=15,
minute=45,
dow="Saturday",
repetition=".+1d",
)
assert ts.active is True
assert ts._year == 2024
assert ts._month == 7
assert ts._day == 20
assert ts.hour == 15
assert ts.minute == 45
assert ts.dow == "Saturday"
assert ts.repetition == ".+1d"
def test_init_without_required_arguments() -> None:
with pytest.raises(ValueError):
Timestamp(active=True)
def test_init_with_partial_date_info() -> None:
with pytest.raises(ValueError):
Timestamp(active=True, year=2024, month=7)
def test_init_with_datetime_overrides_date_info() -> None:
datetime_obj: datetime = datetime(2024, 7, 20, 15, 45)
ts: Timestamp = Timestamp(
active=True, year=2020, month=1, day=1, datetime_=datetime_obj
)
assert ts.active is True
assert ts._year == 2024
assert ts._month == 7
assert ts._day == 20
assert ts.hour == 15
assert ts.minute == 45
assert ts.dow is None
assert ts.repetition is None

View File

@ -2,17 +2,8 @@ import collections
import unittest
from datetime import datetime
from org_rw import (
Bold,
Code,
Italic,
Line,
Strike,
Text,
Underlined,
Verbatim,
get_raw_contents,
)
from org_rw import (Bold, Code, Italic, Line, Strike, Text, Underlined,
Verbatim, get_raw_contents)
def timestamp_to_datetime(ts):