Skip to content

Commit

Permalink
Merge pull request #9 from DeutscheGabanna/tests_setup
Browse files Browse the repository at this point in the history
added tests setup
  • Loading branch information
DeutscheGabanna authored Oct 25, 2023
2 parents c31cdaf + 8923fb6 commit 05c75e9
Show file tree
Hide file tree
Showing 17 changed files with 657 additions and 288 deletions.
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

0 comments on commit 05c75e9

Please sign in to comment.