forked from kenkeiras/org-rw
Compare commits
62 Commits
dev/render
...
develop
Author | SHA1 | Date | |
---|---|---|---|
8280949f23 | |||
|
691ce30a68 | ||
48de06abc7 | |||
|
d4b40e404d | ||
|
5432c23202 | ||
|
8fe3c27595 | ||
|
1dc6eb0b43 | ||
5019b44dd5 | |||
|
78bc57e55d | ||
|
d4b0d0301f | ||
|
92078617fc | ||
|
852f472374 | ||
|
570e6bb764 | ||
|
e0306bf3a5 | ||
bfe60271eb | |||
|
4af4cda44b | ||
|
5552b3324b | ||
|
f31c64c242 | ||
|
490b36887a | ||
05718e1001 | |||
|
e991074346 | ||
|
66b42e0b96 | ||
|
c6d8575ae5 | ||
|
8ca480ad77 | ||
|
0a55c64551 | ||
991781a249 | |||
75055f5e08 | |||
40d58d5488 | |||
|
09f9030818 | ||
|
7e44bce145 | ||
ef893a72a0 | |||
9fea315115 | |||
191bb753c4 | |||
|
b174405c90 | ||
cca2a9ec1c | |||
|
da2d8c8c6d | ||
|
4c169f5d47 | ||
|
f4d63c2f93 | ||
ff841f82f0 | |||
be68d10d7a | |||
f640521b56 | |||
694f3f59e2 | |||
921495fca8 | |||
c5cc14f65c | |||
|
a56ac018a8 | ||
|
423d6f9842 | ||
|
9e994ba323 | ||
|
4fd29819ea | ||
|
985098e091 | ||
|
feb836b2b6 | ||
|
e26a2f04ac | ||
|
9d87d533f4 | ||
|
e4821f02cd | ||
|
1f54307fdb | ||
|
1d0b4cce14 | ||
|
9fb4bce5ef | ||
|
61246da521 | ||
|
da1288a6ba | ||
|
f7ddddb8c9 | ||
|
343d864559 | ||
|
5ed34df57a | ||
|
99e44fd8b2 |
53
.gitea/workflows/tests.yaml
Normal file
53
.gitea/workflows/tests.yaml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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
3
.gitignore
vendored
@ -139,3 +139,6 @@ dmypy.json
|
|||||||
|
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
# Files for PyPI publishing
|
||||||
|
README.md
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
class DrawerNode:
|
class DrawerNode:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.children = []
|
self.children = []
|
||||||
@ -38,11 +41,12 @@ class ListGroupNode:
|
|||||||
self.children.append(child)
|
self.children.append(child)
|
||||||
|
|
||||||
def get_raw(self):
|
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):
|
def __repr__(self):
|
||||||
return "<List: {}>".format(len(self.children))
|
return "<List: {}>".format(len(self.children))
|
||||||
|
|
||||||
|
|
||||||
class TableNode:
|
class TableNode:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.children = []
|
self.children = []
|
||||||
@ -53,21 +57,24 @@ class TableNode:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Table: {}>".format(len(self.children))
|
return "<Table: {}>".format(len(self.children))
|
||||||
|
|
||||||
|
|
||||||
class TableSeparatorRow:
|
class TableSeparatorRow:
|
||||||
def __init__(self, orig=None):
|
def __init__(self, orig=None):
|
||||||
self.orig = orig
|
self.orig = orig
|
||||||
|
|
||||||
|
|
||||||
class TableRow:
|
class TableRow:
|
||||||
def __init__(self, cells, orig=None):
|
def __init__(self, cells, orig=None):
|
||||||
self.cells = cells
|
self.cells = cells
|
||||||
self.orig = orig
|
self.orig = orig
|
||||||
|
|
||||||
|
|
||||||
class Text:
|
class Text:
|
||||||
def __init__(self, content):
|
def __init__(self, content):
|
||||||
self.content = content
|
self.content = content
|
||||||
|
|
||||||
def get_raw(self):
|
def get_raw(self):
|
||||||
return ''.join(self.content.get_raw())
|
return "".join(self.content.get_raw())
|
||||||
|
|
||||||
|
|
||||||
class ListItem:
|
class ListItem:
|
||||||
@ -92,7 +99,7 @@ class CodeBlock(BlockNode):
|
|||||||
def __init__(self, header, subtype, arguments):
|
def __init__(self, header, subtype, arguments):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.header = header
|
self.header = header
|
||||||
self.lines = None
|
self.lines: Optional[List] = None
|
||||||
self.subtype = subtype
|
self.subtype = subtype
|
||||||
self.arguments = arguments
|
self.arguments = arguments
|
||||||
|
|
||||||
@ -100,6 +107,26 @@ class CodeBlock(BlockNode):
|
|||||||
self.lines = lines
|
self.lines = lines
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Code: {}>".format(len(self.lines))
|
return "<Code: {}>".format(len(self.lines or []))
|
||||||
|
|
||||||
|
|
||||||
|
DomNode = Union[
|
||||||
|
DrawerNode,
|
||||||
|
PropertyNode,
|
||||||
|
ListGroupNode,
|
||||||
|
TableNode,
|
||||||
|
TableSeparatorRow,
|
||||||
|
TableRow,
|
||||||
|
Text,
|
||||||
|
ListItem,
|
||||||
|
BlockNode,
|
||||||
|
]
|
||||||
|
|
||||||
|
ContainerDomNode = Union[
|
||||||
|
DrawerNode,
|
||||||
|
ListGroupNode,
|
||||||
|
TableNode,
|
||||||
|
BlockNode,
|
||||||
|
]
|
||||||
|
|
||||||
from .utils import get_raw_contents
|
from .utils import get_raw_contents
|
||||||
|
1093
org_rw/org_rw.py
1093
org_rw/org_rw.py
File diff suppressed because it is too large
Load Diff
0
org_rw/py.typed
Normal file
0
org_rw/py.typed
Normal file
18
org_rw/types.py
Normal file
18
org_rw/types.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
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
|
@ -1,9 +1,19 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from .org_rw import (Bold, Code, Headline, Italic, Line, RawLine, ListItem, Strike, Text,
|
from .org_rw import (
|
||||||
Underlined, Verbatim)
|
Bold,
|
||||||
|
Code,
|
||||||
from .org_rw import dump_contents
|
Headline,
|
||||||
|
Italic,
|
||||||
|
Line,
|
||||||
|
ListItem,
|
||||||
|
RawLine,
|
||||||
|
Strike,
|
||||||
|
Text,
|
||||||
|
Underlined,
|
||||||
|
Verbatim,
|
||||||
|
dump_contents,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_hl_raw_contents(doc: Headline) -> str:
|
def get_hl_raw_contents(doc: Headline) -> str:
|
||||||
|
11
scripts/apply-formatting.sh
Executable file
11
scripts/apply-formatting.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cd "`dirname $0`"
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
isort --profile black .
|
||||||
|
black .
|
@ -5,6 +5,8 @@ set -eu
|
|||||||
cd "`dirname $0`"
|
cd "`dirname $0`"
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
pandoc README.org -o README.md # PyPI doesn't accept Org files
|
||||||
|
|
||||||
python setup.py sdist
|
python setup.py sdist
|
||||||
|
|
||||||
twine upload --verbose dist/*
|
twine upload --verbose dist/*
|
||||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="org-rw",
|
name="org-rw",
|
||||||
version="0.0.1.dev1",
|
version="0.0.2",
|
||||||
description="Library to de/serialize org-files and manipulate them.",
|
description="Library to de/serialize org-files and manipulate them.",
|
||||||
author="kenkeiras",
|
author="kenkeiras",
|
||||||
author_email="kenkeiras@codigoparallevar.com",
|
author_email="kenkeiras@codigoparallevar.com",
|
||||||
|
@ -21,3 +21,10 @@
|
|||||||
This is a [[https://codigoparallevar.com/4][[tricky web link]]] followed up with some text.
|
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.
|
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.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
:CREATED: [2020-01-01 Wed 01:01]
|
:CREATED: [2020-01-01 Wed 01:01]
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
|
#+NAME: first-code-name
|
||||||
#+BEGIN_SRC shell :results verbatim
|
#+BEGIN_SRC shell :results verbatim
|
||||||
echo "This is a test"
|
echo "This is a test"
|
||||||
echo "with two lines"
|
echo "with two lines"
|
||||||
|
22
tests/12-headlines-with-skip-levels.org
Normal file
22
tests/12-headlines-with-skip-levels.org
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#+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
|
||||||
|
|
13
tests/13-tags.org
Normal file
13
tests/13-tags.org
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#+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:
|
@ -1,14 +1,23 @@
|
|||||||
import logging
|
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import date
|
|
||||||
from datetime import datetime as DT
|
from datetime import datetime as DT
|
||||||
|
|
||||||
from org_rw import MarkerToken, MarkerType, Timestamp, dumps, load, loads, dom
|
from utils.assertions import (
|
||||||
import org_rw
|
BOLD,
|
||||||
|
CODE,
|
||||||
|
HL,
|
||||||
|
ITALIC,
|
||||||
|
SPAN,
|
||||||
|
STRIKE,
|
||||||
|
UNDERLINED,
|
||||||
|
VERBATIM,
|
||||||
|
WEB_LINK,
|
||||||
|
Doc,
|
||||||
|
Tokens,
|
||||||
|
)
|
||||||
|
|
||||||
from utils.assertions import (BOLD, CODE, HL, ITALIC, SPAN, STRIKE, UNDERLINED,
|
import org_rw
|
||||||
VERBATIM, WEB_LINK, Doc, Tokens)
|
from org_rw import MarkerToken, MarkerType, Timestamp, dom, dumps, load, loads
|
||||||
|
|
||||||
DIR = os.path.dirname(os.path.abspath(__file__))
|
DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
@ -202,7 +211,7 @@ class TestSerde(unittest.TestCase):
|
|||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
links = list(doc.get_links())
|
links = list(doc.get_links())
|
||||||
self.assertEqual(len(links), 7)
|
self.assertEqual(len(links), 8)
|
||||||
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
|
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
|
||||||
self.assertEqual(links[0].description, "web link")
|
self.assertEqual(links[0].description, "web link")
|
||||||
|
|
||||||
@ -224,6 +233,9 @@ class TestSerde(unittest.TestCase):
|
|||||||
self.assertEqual(links[6].value, "https://codigoparallevar.com/5")
|
self.assertEqual(links[6].value, "https://codigoparallevar.com/5")
|
||||||
self.assertEqual(links[6].description, "another tricky web link")
|
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(
|
ex = Doc(
|
||||||
props=[
|
props=[
|
||||||
("TITLE", "03-Links"),
|
("TITLE", "03-Links"),
|
||||||
@ -280,17 +292,35 @@ class TestSerde(unittest.TestCase):
|
|||||||
SPAN("\n"),
|
SPAN("\n"),
|
||||||
SPAN(
|
SPAN(
|
||||||
" This is a ",
|
" 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",
|
" followed up with some text.\n",
|
||||||
),
|
),
|
||||||
SPAN("\n"),
|
SPAN("\n"),
|
||||||
SPAN(
|
SPAN(
|
||||||
" This is [",
|
" 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",
|
"] 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",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -301,7 +331,7 @@ class TestSerde(unittest.TestCase):
|
|||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
links = list(doc.get_links())
|
links = list(doc.get_links())
|
||||||
self.assertEqual(len(links), 7)
|
self.assertEqual(len(links), 8)
|
||||||
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
|
self.assertEqual(links[0].value, "https://codigoparallevar.com/1")
|
||||||
self.assertEqual(links[0].description, "web link")
|
self.assertEqual(links[0].description, "web link")
|
||||||
links[0].value = "https://codigoparallevar.com/1-updated"
|
links[0].value = "https://codigoparallevar.com/1-updated"
|
||||||
@ -337,6 +367,9 @@ class TestSerde(unittest.TestCase):
|
|||||||
links[6].value = "https://codigoparallevar.com/5-updated"
|
links[6].value = "https://codigoparallevar.com/5-updated"
|
||||||
links[6].description = "another tricky web link #5 with update"
|
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(
|
ex = Doc(
|
||||||
props=[
|
props=[
|
||||||
("TITLE", "03-Links"),
|
("TITLE", "03-Links"),
|
||||||
@ -416,7 +449,19 @@ class TestSerde(unittest.TestCase):
|
|||||||
"] followed up with some text.\n",
|
"] 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",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -435,18 +480,22 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
snippets = list(doc.get_code_snippets())
|
snippets = list(doc.get_code_snippets())
|
||||||
self.assertEqual(len(snippets), 3)
|
self.assertEqual(len(snippets), 3)
|
||||||
|
self.assertEqual(snippets[0].name, "first-code-name")
|
||||||
|
self.assertEqual(snippets[0].language, "shell")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
snippets[0].content,
|
snippets[0].content,
|
||||||
'echo "This is a test"\n'
|
'echo "This is a test"\n'
|
||||||
+ 'echo "with two lines"\n'
|
+ 'echo "with two lines"\n'
|
||||||
+ "exit 0 # Exit successfully",
|
+ "exit 0 # Exit successfully",
|
||||||
)
|
)
|
||||||
self.assertEqual(snippets[0].arguments.split(), ['shell', ':results', 'verbatim'])
|
self.assertEqual(snippets[0].arguments.split(), [":results", "verbatim"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
snippets[0].result,
|
snippets[0].result,
|
||||||
"This is a test\n" + "with two lines",
|
"This is a test\n" + "with two lines",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.assertEqual(snippets[1].name, None)
|
||||||
|
self.assertEqual(snippets[1].language, "shell")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
snippets[1].content,
|
snippets[1].content,
|
||||||
'echo "This is another test"\n'
|
'echo "This is another test"\n'
|
||||||
@ -457,12 +506,14 @@ class TestSerde(unittest.TestCase):
|
|||||||
snippets[1].result, "This is another test\n" + "with two lines too"
|
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(
|
self.assertEqual(
|
||||||
snippets[2].content,
|
snippets[2].content,
|
||||||
'/* This code has to be escaped to\n'
|
"/* This code has to be escaped to\n"
|
||||||
+ ' * avoid confusion with new headlines.\n'
|
+ " * avoid confusion with new headlines.\n"
|
||||||
+ ' */\n'
|
+ " */\n"
|
||||||
+ 'main(){}',
|
+ "main(){}",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_mimic_write_file_05(self):
|
def test_mimic_write_file_05(self):
|
||||||
@ -500,7 +551,7 @@ class TestSerde(unittest.TestCase):
|
|||||||
hl_schedule_range = hl.children[1]
|
hl_schedule_range = hl.children[1]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
hl_schedule_range.scheduled.time,
|
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(
|
self.assertEqual(
|
||||||
hl_schedule_range.scheduled.end_time,
|
hl_schedule_range.scheduled.end_time,
|
||||||
@ -508,7 +559,7 @@ class TestSerde(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
hl_schedule_range.scheduled.repetition,
|
hl_schedule_range.scheduled.repetition,
|
||||||
'++1w',
|
"++1w",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_update_info_file_05(self):
|
def test_update_info_file_05(self):
|
||||||
@ -561,7 +612,8 @@ class TestSerde(unittest.TestCase):
|
|||||||
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
|
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
|
||||||
"markup",
|
"markup",
|
||||||
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
|
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
|
||||||
".", "\n"
|
".",
|
||||||
|
"\n",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -595,12 +647,24 @@ class TestSerde(unittest.TestCase):
|
|||||||
print(lists4)
|
print(lists4)
|
||||||
self.assertEqual(len(lists4), 2)
|
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][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[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, "-")
|
self.assertEqual(lists4[1][0].bullet, "-")
|
||||||
|
|
||||||
def test_org_roam_07(self):
|
def test_org_roam_07(self):
|
||||||
@ -644,20 +708,22 @@ class TestSerde(unittest.TestCase):
|
|||||||
""".strip(),
|
""".strip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_markup_file_09(self):
|
def test_markup_file_09(self):
|
||||||
with open(os.path.join(DIR, "09-markup-on-headline.org")) as f:
|
with open(os.path.join(DIR, "09-markup-on-headline.org")) as f:
|
||||||
doc = load(f)
|
doc = load(f)
|
||||||
|
|
||||||
hl = doc.getTopHeadlines()[0]
|
hl = doc.getTopHeadlines()[0]
|
||||||
print(hl.title)
|
print(hl.title)
|
||||||
self.assertEqual(hl.title.contents, [
|
self.assertEqual(
|
||||||
'Headline ',
|
hl.title.contents,
|
||||||
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
|
[
|
||||||
'with',
|
"Headline ",
|
||||||
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
|
MarkerToken(closing=False, tok_type=MarkerType.UNDERLINED_MODE),
|
||||||
' markup',
|
"with",
|
||||||
])
|
MarkerToken(closing=True, tok_type=MarkerType.UNDERLINED_MODE),
|
||||||
|
" markup",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def test_mimic_write_file_10(self):
|
def test_mimic_write_file_10(self):
|
||||||
with open(os.path.join(DIR, "10-tables.org")) as f:
|
with open(os.path.join(DIR, "10-tables.org")) as f:
|
||||||
@ -678,9 +744,9 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
print(first_table[0])
|
print(first_table[0])
|
||||||
self.assertEqual(len(first_table[0].cells), 3)
|
self.assertEqual(len(first_table[0].cells), 3)
|
||||||
self.assertEqual(first_table[0].cells[0].strip(), 'Header1')
|
self.assertEqual(first_table[0].cells[0].strip(), "Header1")
|
||||||
self.assertEqual(first_table[0].cells[1].strip(), 'Header2')
|
self.assertEqual(first_table[0].cells[1].strip(), "Header2")
|
||||||
self.assertEqual(first_table[0].cells[2].strip(), 'Header3')
|
self.assertEqual(first_table[0].cells[2].strip(), "Header3")
|
||||||
|
|
||||||
hl = hl.children[0]
|
hl = hl.children[0]
|
||||||
|
|
||||||
@ -690,9 +756,9 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
print(first_table[0])
|
print(first_table[0])
|
||||||
self.assertEqual(len(first_table[0].cells), 3)
|
self.assertEqual(len(first_table[0].cells), 3)
|
||||||
self.assertEqual(first_table[0].cells[0].strip(), 'Header1')
|
self.assertEqual(first_table[0].cells[0].strip(), "Header1")
|
||||||
self.assertEqual(first_table[0].cells[1].strip(), 'Header2')
|
self.assertEqual(first_table[0].cells[1].strip(), "Header2")
|
||||||
self.assertEqual(first_table[0].cells[2].strip(), 'Header3')
|
self.assertEqual(first_table[0].cells[2].strip(), "Header3")
|
||||||
|
|
||||||
def test_tables_html_file_10(self):
|
def test_tables_html_file_10(self):
|
||||||
with open(os.path.join(DIR, "10-tables.org")) as f:
|
with open(os.path.join(DIR, "10-tables.org")) as f:
|
||||||
@ -702,27 +768,26 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
tree = hl.as_dom()
|
tree = hl.as_dom()
|
||||||
non_props = [
|
non_props = [
|
||||||
item
|
item for item in tree if not isinstance(item, dom.PropertyDrawerNode)
|
||||||
for item in tree
|
|
||||||
if not isinstance(item, dom.PropertyDrawerNode)
|
|
||||||
]
|
]
|
||||||
self.assertTrue(isinstance(non_props[0], dom.Text)
|
self.assertTrue(
|
||||||
and isinstance(non_props[1], dom.TableNode)
|
isinstance(non_props[0], dom.Text)
|
||||||
and isinstance(non_props[2], dom.Text),
|
and isinstance(non_props[1], dom.TableNode)
|
||||||
'Expected <Text><Table><Text>')
|
and isinstance(non_props[2], dom.Text),
|
||||||
|
"Expected <Text><Table><Text>",
|
||||||
|
)
|
||||||
|
|
||||||
hl = hl.children[0]
|
hl = hl.children[0]
|
||||||
tree = hl.as_dom()
|
tree = hl.as_dom()
|
||||||
non_props = [
|
non_props = [
|
||||||
item
|
item
|
||||||
for item in tree
|
for item in tree
|
||||||
if not (isinstance(item, dom.PropertyDrawerNode)
|
if not (
|
||||||
or isinstance(item, dom.Text))
|
isinstance(item, dom.PropertyDrawerNode) or isinstance(item, dom.Text)
|
||||||
|
)
|
||||||
]
|
]
|
||||||
print_tree(non_props)
|
print_tree(non_props)
|
||||||
self.assertTrue(len(non_props) == 1,
|
self.assertTrue(len(non_props) == 1, "Expected <List>, with only (1) element")
|
||||||
'Expected <List>, with only (1) element')
|
|
||||||
|
|
||||||
def test_nested_lists_html_file_11(self):
|
def test_nested_lists_html_file_11(self):
|
||||||
with open(os.path.join(DIR, "11-nested-lists.org")) as f:
|
with open(os.path.join(DIR, "11-nested-lists.org")) as f:
|
||||||
@ -732,30 +797,232 @@ class TestSerde(unittest.TestCase):
|
|||||||
|
|
||||||
tree = hl.as_dom()
|
tree = hl.as_dom()
|
||||||
non_props = [
|
non_props = [
|
||||||
item
|
item for item in tree if not isinstance(item, dom.PropertyDrawerNode)
|
||||||
for item in tree
|
|
||||||
if not isinstance(item, dom.PropertyDrawerNode)
|
|
||||||
]
|
]
|
||||||
print_tree(non_props)
|
print_tree(non_props)
|
||||||
self.assertTrue((len(non_props) == 1) and (isinstance(non_props[0], dom.ListGroupNode)),
|
self.assertTrue(
|
||||||
'Expected only <List> as top level')
|
(len(non_props) == 1) and (isinstance(non_props[0], dom.ListGroupNode)),
|
||||||
|
"Expected only <List> as top level",
|
||||||
|
)
|
||||||
|
|
||||||
dom_list = non_props[0]
|
dom_list = non_props[0]
|
||||||
children = dom_list.children
|
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
|
# Assert texts
|
||||||
self.assertEqual(children[0].content, ['1'])
|
self.assertEqual(children[0].content, ["1"])
|
||||||
self.assertEqual(children[2].content, ['2'])
|
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[4].content[0], "3"
|
||||||
|
) # Might be ['3', '\n'] but shouldn't be a breaking change
|
||||||
|
|
||||||
# Assert lists
|
# Assert lists
|
||||||
self.assertTrue(isinstance(children[1], dom.ListGroupNode), 'Expected sublist inside "1"')
|
self.assertTrue(
|
||||||
self.assertEqual(children[1].children[0].content, ['1.1'])
|
isinstance(children[1], dom.ListGroupNode), 'Expected sublist inside "1"'
|
||||||
self.assertEqual(children[1].children[1].content, ['1.2'])
|
)
|
||||||
self.assertTrue(isinstance(children[3], dom.ListGroupNode), 'Expected sublist inside "2"')
|
self.assertEqual(children[1].children[0].content, ["1.1"])
|
||||||
self.assertEqual(children[3].children[0].content, ['2.1'])
|
self.assertEqual(children[1].children[1].content, ["1.2"])
|
||||||
self.assertEqual(children[3].children[1].content, ['2.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")
|
||||||
|
|
||||||
|
|
||||||
def print_tree(tree, indentation=0, headline=None):
|
def print_tree(tree, indentation=0, headline=None):
|
||||||
@ -775,6 +1042,10 @@ def print_element(element, indentation, headline):
|
|||||||
if isinstance(element, org_rw.Link):
|
if isinstance(element, org_rw.Link):
|
||||||
print(" " * indentation * 2, "Link:", element.get_raw())
|
print(" " * indentation * 2, "Link:", element.get_raw())
|
||||||
elif isinstance(element, str):
|
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:
|
else:
|
||||||
print_tree(element, indentation, headline)
|
print_tree(element, indentation, headline)
|
||||||
|
86
tests/test_timestamp.py
Normal file
86
tests/test_timestamp.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
"""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
|
@ -2,8 +2,17 @@ import collections
|
|||||||
import unittest
|
import unittest
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from org_rw import (Bold, Code, Italic, Line, Strike, Text, Underlined,
|
from org_rw import (
|
||||||
Verbatim, get_raw_contents)
|
Bold,
|
||||||
|
Code,
|
||||||
|
Italic,
|
||||||
|
Line,
|
||||||
|
Strike,
|
||||||
|
Text,
|
||||||
|
Underlined,
|
||||||
|
Verbatim,
|
||||||
|
get_raw_contents,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def timestamp_to_datetime(ts):
|
def timestamp_to_datetime(ts):
|
||||||
|
Loading…
Reference in New Issue
Block a user