Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added tests setup #9

Merged
merged 8 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Test

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Unittest main.py
run: |
python _tests/test_main.py
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
*.csv
*.md
__pycache__/
_tests/computed_results
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true
// "args": [
// "./_tests/testing_sheet.csv",
// "~/Daylio export/"
// ]
}
]
}
15 changes: 15 additions & 0 deletions _tests/expected_results/2022-10-25.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
tags: daily
---

## hungry - 11:36 PM
I felt #hungry with the following: #allegro #working-remotely #colleague-interaction
Nulla vel risus eget magna lacinia aliquam ac in arcu.

## rad - 11:40 PM
I felt #rad.
Uet nulla nunc lobortis quisque.

## vaguely ok - 5:00 PM
I felt #vaguely-ok.

28 changes: 28 additions & 0 deletions _tests/expected_results/2022-10-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
tags: daily
---

## captivated - 10:00 PM
I felt #captivated with the following: #at-the-office #board-game #colleague-interaction #big-social-gathering
Sed ut est interdum

## tired - 8:00 PM
I felt #tired with the following: #allegro #at-the-office #board-game #colleague-interaction #big-social-gathering
Quisque dictum odio quis augue consectetur, at convallis żodio aliquam.

## grateful - 7:30 PM
I felt #grateful with the following: #allegro #at-the-office #acknowledged-efforts #colleague-interaction
Nulla aćcumsan sem sit amet lectus pretium, ac interdum tellus porta.

## blissful - 1:00 PM
I felt #blissful with the following: #allegro #at-the-office
Ut et elit id lectus hendrerit ełementum quis auctor ipsum.

## in awe - 9:00 AM
I felt #in-awe with the following: #allegro #at-the-office #outdoors #notable-event
Nunc lobortis enim eu nisi ultrices, sit amet sagittis lacus venenatis.

## lifeless - 7:50 AM
I felt #lifeless with the following: #podcast #politics #world-event
Etiam commódo enim ut orci varius viverra.

12 changes: 12 additions & 0 deletions _tests/expected_results/2022-10-27.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
tags: daily
---

## vaguely good - 1:49 PM
I felt #vaguely-good with the following: #chess
Lorem ipsum dolor sit amet, consectetur adipiscing elit.

## fatigued - 12:00 AM
I felt #fatigued with the following: #allegro #working-remotely
Phaśellus pharetra justo ac dui lacinia ullamcorper.

8 changes: 8 additions & 0 deletions _tests/expected_results/2022-10-30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
tags: daily
---

## vaguely ok - 10:04 AM
I felt #vaguely-ok with the following: #2ćities-skylines #dólóó-fas_ą
Lorem ipsum sit dolomet amęt.

120 changes: 120 additions & 0 deletions _tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""Test cases for main.py"""
import unittest
import shutil # to delete temporary files
import subprocess # to run main.py
import os # to make temporary directories and join them

# import csv
# # Custom
# import parse_csv
# import utils

# class TestScript(unittest.TestCase):
# def test_expanded_path(self):
# self.assertEqual(
# utils.expand_path(r"./_tests/testing_sheet.csv"),
# r"/home/deutschegabanna/Obsidian-Daylio-Parser/_tests/testing_sheet.csv"
# )

# def test_this_row(self, row_to_parse, time, mood, activities, title, note):
# """Checks if Entry object correctly parses CSV row and populates its parameters.
# time, mood, activities, title, and note in function arguments should be the expected values."""
# tmp_entry = parse_csv.Entry(csv.reader([row_to_parse], delimiter=',', quotechar='"'))
# self.assertEqual(tmp_entry.time, time, "Entry created with wrong time.")
# self.assertEqual(tmp_entry.mood, mood, "Entry created with wrong mood.")
# self.assertListEqual(tmp_entry.activities, activities, "Entry created with wrong activities array.")
# self.assertEqual(tmp_entry.title, title, "Entry created with wrong title.")
# self.assertEqual(tmp_entry.note, note, "Entry created with wrong note.")

# def test_parsing(self):
# """Check several rows to trigger test_this_row for each of them."""
# # Sample entry
# self.test_this_row(
# "2022-10-30,October 30,Sunday,10:04 AM,vaguely ok,2ćities skylines | dó#lóó fa$$s_ą%,\"Dolomet\",\"Lorem ipsum sit dolomet amęt.\"",
# "10:04 AM",
# "vaguely ok",
# ["2ćities-skylines", "dólóó-fas_ą"],
# "Dolomet",
# "Lorem ipsum sit dolomet amęt."
# )
# # Sample entry
# self.test_this_row(
# "2022-10-27,October 27,Thursday,1:49 PM,vaguely good,chess,\"Cras pretium\",\"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\"",
# "1:49 PM",
# "vaguely good",
# ["chess"],
# "Cras pretium",
# "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
# )
# # Sample entry
# self.test_this_row(
# "2022-10-29,October 29,Saturday,3:30 PM,happy,drawing,\"Art session\",\"Had a great time drawing today.\"",
# "3:30 PM",
# "happy",
# ["drawing"],
# "Art session",
# "Had a great time drawing today."
# )
# # Sample entry
# self.test_this_row(
# "2022-10-28,October 28,Wednesday,9:15 AM,sad,reading,\"A good book\",\"Enjoyed reading for a while.\"",
# "9:15 AM",
# "sad",
# ["reading"],
# "A good book",
# "Enjoyed reading for a while."
# )


# def test_parsing_incomplete_data(self):
# """Check if Entry object correctly consumes an array with incomplete data"""
# sample_row = [
# "2022-10-30",
# "October 30",
# "Sunday",
# "10:04 AM",
# "vaguely ok"
# ]
# try:
# sample_entry = parse_csv.Entry(sample_row)
# except IndexError:
# pass
# else:
# pass

FILES = [
"2022-10-25.md",
"2022-10-26.md",
"2022-10-27.md",
"2022-10-30.md"
]
TEST_DIR = os.path.join(os.getcwd(), "_tests")
COMPUTED = os.path.join(TEST_DIR, "computed_results")
EXPECTED = os.path.join(TEST_DIR, "expected_results")

class TestScript(unittest.TestCase):
"""Tests ../main.py"""
def setUp(self):
"""Create temporary directory for test output files"""
if not os.path.exists(COMPUTED):
os.mkdir(COMPUTED)

def test_main(self):
"""Gives ../main.py a CSV file and checks whether it is identical to the expected_results"""
if not subprocess.run(["python", "main.py", os.path.join(TEST_DIR, "testing_sheet.csv"), COMPUTED], check=True):
self.fail()

# Open each computed file and check if it's equal to the expected one
for file in FILES:
with open(os.path.join(EXPECTED, file), encoding="UTF-8") as expected_file, open(os.path.join(COMPUTED, file), encoding="UTF-8") as computed_file:
self.assertListEqual(list(expected_file), list(computed_file))

def tearDown(self):
if os.path.isdir(COMPUTED):
shutil.rmtree(COMPUTED)
else:
raise FileNotFoundError(f"{COMPUTED} is missing at teardown.")

# is this run as a main program, not component?
if __name__ == '__main__':
unittest.main(argv=["first-arg-is-ignored"])
13 changes: 13 additions & 0 deletions _tests/testing_sheet.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
full_date,date,weekday,time,mood,activities,note_title,note
2022-10-30,October 30,Sunday,10:04 AM,vaguely ok,2ćities skylines | dó#lóó fa$$s_ą%,"Dolomet","Lorem ipsum sit dolomet amęt."
2022-10-27,October 27,Thursday,1:49 PM,vaguely good,chess,"Cras pretium","Lorem ipsum dolor sit amet, consectetur adipiscing elit."
2022-10-27,October 27,Thursday,12:00 AM,fatigued,allegro | working remotely,"Suspendisse sit amet","Phaśellus pharetra justo ac dui lacinia ullamcorper."
2022-10-26,October 26,Wednesday,10:00 PM,captivated,at the office | board game | colleague interaction | big social gathering,,"Sed ut est interdum","Maecenas dictum augue in nibh pellentesque porttitor."
2022-10-26,October 26,Wednesday,8:00 PM,tired,allegro | at the office | board game | colleague interaction | big social gathering,"Mauris rutrum diam","Quisque dictum odio quis augue consectetur, at convallis żodio aliquam."
2022-10-26,October 26,Wednesday,7:30 PM,grateful,allegro | at the office | acknowledged efforts | colleague interaction,"Aliquam nec sem semper","Nulla aćcumsan sem sit amet lectus pretium, ac interdum tellus porta."
2022-10-26,October 26,Wednesday,1:00 PM,blissful,allegro | at the office,"Vestibulum sagittis leo eu sodales","Ut et elit id lectus hendrerit ełementum quis auctor ipsum."
2022-10-26,October 26,Wednesday,9:00 AM,in awe,allegro | at the office | outdoors | notable event,"Integer elementum","Nunc lobortis enim eu nisi ultrices, sit amet sagittis lacus venenatis."
2022-10-26,October 26,Wednesday,7:50 AM,lifeless,podcast | politics | world event,"Nulla quis lectus pulvinar","Etiam commódo enim ut orci varius viverra."
2022-10-25,October 25,Tuesday,11:36 PM,hungry,allegro | working remotely | colleague interaction,"Mauris vitae nunc vel arcu consequat auctor","Nulla vel risus eget magna lacinia aliquam ac in arcu."
2022-10-25,October 25,Tuesday,11:40 PM,rad,,,Uet nulla nunc lobortis quisque.
2022-10-25,October 25,Tuesday,5:00 PM,vaguely ok,,,
67 changes: 67 additions & 0 deletions cmd_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""Sets up all necessary options and arguments for main.py"""
import argparse

parser = argparse.ArgumentParser(
prog="Daylio to Obsidian Parser",
description="Converts Daylio .CSV backup file into Markdown files for Obsidian.",
epilog="Created by DeutscheGabanna"
)
parser.add_argument(
"filepath",
type=str,
help="Specify path to the .CSV file"
)
parser.add_argument(
"destination",
help="Path to output finished files into."
)
parser.add_argument(
"--prefix", # <here's your prefix>YYYY-MM-DD.md so remember about a separating char
default='',
help="Prepends a given string to each entry's header."
)
parser.add_argument(
"--suffix", # YYYY-MM-DD<here's your suffix>.md so remember about a separating char
default='',
help="Appends a given string at the end of each entry's header."
)
parser.add_argument(
"--tag_activities", "-a",
action="store_true",
help="Tries to convert activities into valid tags.",
dest="ACTIVITIES_AS_TAGS"
)
parser.add_argument(
"-colour", "--color",
action="store_true",
help="Prepends a colour emoji to each entry depending on mood.",
dest="colour"
)
parser.add_argument('--version', action='version', version='%(prog)s 2.0')
parser.add_argument(
"--header",
type=int,
default=2,
help="Headings level for each entry.",
dest="HEADER_LEVEL"
)
parser.add_argument(
"--tags",
help="Tags in the YAML metamood_to_check of each note.",
default="daily",
dest="TAGS"
)
# TODO: Force-argument does nothing yet.
parser.add_argument(
"--force",
choices=["accept", "refuse"],
help="Skips user confirmation when overwriting files. Either force 'accept' (DANGEROUS!) or 'refuse' all requests."
)
parser.add_argument(
"--csv-delimiter",
default="|",
help="Set delimiter for activities in Daylio .CSV, e.g: football | chess"
)
# TODO: User should be able to set verbosity level in logging

settings = parser.parse_args()
70 changes: 70 additions & 0 deletions compile_md.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""COMPILE STRUCTURED DATA INTO STRING TO OUTPUT
---------------------------------------------
According to this schema:
---
tags: <your_custom_tags>
---

### <hour> / <title>
#activity_1 #activity_2 #activity_3
<your_entry>

[repeat]
"""
import logging
from functools import reduce
# Other
from cmd_args import settings
import load_moods
import utils

def compile_note_yaml():
"""Returns string with YAML metadata for each note. It looks like this:
---
tags: <your_custom_tags>
---
"""
return f"---\ntags: {settings.TAGS} \n---\n\n"

def compile_entry_contents(entry):
"""Return a string that is a parsed entry from Daylio CSV as a string.
It looks like this:

### <hour> / <title>
#activity_1 #activity_2 #activity_3
<your_entry>

"""
# compose the title with optional mood colouring
this_entry_title = get_colour(entry.mood) + entry.mood + " - " + entry.time
final_output = settings.HEADER_LEVEL*'#' + " " + this_entry_title

# compose the mood-tag and the activity-tags into one paragraph
final_output += "\nI felt #"
final_output += utils.slugify(entry.mood, settings.ACTIVITIES_AS_TAGS)
if len(entry.activities) > 0 and entry.activities[0] != "":
final_output += " with the following: "
## first append # to each activity, then mush them together into one string
final_output += reduce(
lambda el1,el2 : el1+" "+el2, map(lambda x:"#"+x,entry.activities)
)
else: final_output += "."

## then add the rest of the text
if entry.note != "":
final_output += "\n" + entry.note + "\n\n"
else:
final_output += "\n\n"
return final_output

def get_colour(mood_to_check):
"""Prepend appropriate colour for the mood passed in mood_to_check"""
prepended_colour = ""
mood_colour=["🟣","🟢","🔵","🟠","🔴"] # 0 - best, 4 - worst mood group
if settings.colour:
for i, (_, this_group) in enumerate(load_moods.available_moods.items()):
if mood_to_check in this_group:
prepended_colour = f"{mood_colour[i]} "
if not prepended_colour:
logging.warning("%s was not found in moods.json database.", mood_to_check)
return prepended_colour
8 changes: 8 additions & 0 deletions load_moods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Provides a 2D array of mood groups and associated moods based on the moods.json file"""
import json

# MOODS are used to determine colour coding for the particular moods if colour = TRUE
# [0,x] - best, [4,x] - worst

with open("moods.json", encoding="UTF-8") as jsonfile:
available_moods = json.load(jsonfile)
Loading
Loading