@@ -1,4 +1,4 @@ | |||
name: E2E tests | |||
name: Tests | |||
on: | |||
push: | |||
@@ -17,14 +17,15 @@ jobs: | |||
fail-fast: false | |||
matrix: | |||
os: | |||
- ubuntu-18.04 | |||
- ubuntu-20.04 | |||
- ubuntu-latest | |||
- macos-latest | |||
python-version: | |||
- '3.7' | |||
- '3.8' | |||
- '3.9' | |||
- '3.10' | |||
name: E2E tests (Python ${{ matrix.python-version }} on ${{ matrix.os }}) | |||
name: Python ${{ matrix.python-version }} on ${{ matrix.os }} | |||
steps: | |||
- uses: actions/checkout@v1 | |||
@@ -35,20 +36,30 @@ jobs: | |||
- name: Prepare tests | |||
run: | | |||
sudo apt update | |||
sudo apt install ruby | |||
sudo gem install ronn | |||
pip install -U setuptools pip requests wheel Babel | |||
pip install -U pip pipenv | |||
pipenv sync --dev | |||
make manpage | |||
- name: E2E tests | |||
run: | | |||
export ENVIRONMENT="CI" | |||
bash .scripts/tests-e2e.sh | |||
make tests | |||
- name: Install TeXLive (Ubuntu) | |||
if: ${{ matrix.os == 'ubuntu-latest' }} | |||
run: | | |||
sudo apt-get install -y texlive texlive-latex-extra | |||
- name: E2E tests | |||
env: | |||
TEXLIVE_INSTALLED: 1 | |||
run: | | |||
make tests | |||
- name: manpage (section 1) | |||
run: | | |||
man -P $(which cat) kosmorro | |||
man -P $(which cat) manpage/kosmorro.1 | |||
- name: manpage (section 7) | |||
run: | | |||
man -P $(which cat) 7 kosmorro | |||
man -P $(which cat) manpage/kosmorro.7 |
@@ -1,128 +0,0 @@ | |||
#!/bin/bash | |||
VERSION=$(grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' _kosmorro/__version__.py) | |||
PYTHON_BIN=$(command -v python) | |||
PIP_BIN=$(command -v pip) | |||
if python3 --version > /dev/null; then | |||
PYTHON_BIN=$(command -v python3) | |||
PIP_BIN=$(command -v pip3) | |||
fi | |||
failures='' | |||
function fail() { | |||
failures="$failures\n\n - $1\n\n$2" | |||
} | |||
function run() { | |||
eval "$1" &> /tmp/output.txt | |||
return $? | |||
} | |||
function canRun() { | |||
if [[ "$1" != "" && "$1" != "$ENVIRONMENT" ]]; then | |||
return 1 | |||
fi | |||
return 0 | |||
} | |||
# Asserts that command $1 has finished with sucess | |||
# $1: the command to run | |||
function assertSuccess() { | |||
if ! canRun "$2"; then | |||
echo -n 'I' | |||
return | |||
fi | |||
run "$1" | |||
returned=$? | |||
if [ $returned -ne 0 ]; then | |||
fail "Failed asserting that command '$1' finishes with success, returned status $returned." "$(cat /tmp/output.txt)" | |||
echo -n 'F' | |||
return | |||
fi | |||
echo -n '.' | |||
} | |||
# Asserts that command $1 has finished with sucess | |||
# $1: the command to run | |||
function assertFailure() { | |||
if ! canRun "$2"; then | |||
echo -n 'I' | |||
return | |||
fi | |||
run "$1" | |||
returned=$? | |||
if [ $returned -eq 0 ]; then | |||
fail "Failed asserting that command '$1' finishes with failure." "$(cat /tmp/output.txt)" | |||
echo -n 'F' | |||
return | |||
fi | |||
echo -n '.' | |||
} | |||
mkdir -p $HOME/kosmorro/export | |||
echo | |||
echo "==== RUNNING E2E TESTS ====" | |||
echo | |||
# Create the package and install it | |||
assertSuccess "make build" | |||
assertSuccess "$PIP_BIN install dist/kosmorro-$VERSION.tar.gz" "CI" | |||
KOSMORRO_COMMAND="kosmorro --debug" | |||
assertSuccess "$KOSMORRO_COMMAND" | |||
assertSuccess "$KOSMORRO_COMMAND -h" | |||
assertSuccess "$KOSMORRO_COMMAND -d 2020-01-27" | |||
assertFailure "$KOSMORRO_COMMAND -d yolo-yo-lo" | |||
assertFailure "$KOSMORRO_COMMAND -d 2020-13-32" | |||
assertFailure "$KOSMORRO_COMMAND --date=1789-05-05" | |||
assertFailure "$KOSMORRO_COMMAND --date=3000-01-01" | |||
assertSuccess "$KOSMORRO_COMMAND --date='+3y 5m3d'" | |||
assertSuccess "$KOSMORRO_COMMAND --date='-1y3d'" | |||
assertFailure "$KOSMORRO_COMMAND --date='+3d4m" | |||
assertFailure "$KOSMORRO_COMMAND -date='3y'" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --timezone=1" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --timezone=-1" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=json" | |||
assertFailure "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf" | |||
assertSuccess "$KOSMORRO_COMMAND -d 2020-01-27 --format=json" | |||
# Environment variables | |||
assertSuccess "LATITUDE=50.5876 LONGITUDE=3.0624 TIMEZONE=1 kosmorro -d 2020-01-27" | |||
assertSuccess "LATITUDE=50.5876 LONGITUDE=3.0624 TIMEZONE=-1 kosmorro -d 2020-01-27" | |||
# Missing dependencies, should fail | |||
assertFailure "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o $HOME/kosmorro/export/document.pdf" | |||
assertFailure "ls $HOME/kosmorro/export/document.pdf" | |||
assertSuccess "sudo apt-get install -y texlive texlive-latex-extra" "CI" | |||
# Dependencies installed, should not fail | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o $HOME/kosmorro/export/document.pdf" | |||
assertSuccess "ls $HOME/kosmorro/export/document.pdf" | |||
assertSuccess "$KOSMORRO_COMMAND --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o $HOME/kosmorro/export/document-no-graph.pdf --no-graph" | |||
assertSuccess "ls $HOME/kosmorro/export/document-no-graph.pdf" | |||
# man page | |||
assertSuccess "man --pager=cat kosmorro" | |||
if [ "$failures" != "" ]; then | |||
echo -e "\n$failures" | |||
exit 2 | |||
fi | |||
echo -e "\n\n==== TESTS RAN SUCCESSFULLY 👍 ====" |
@@ -1,5 +1,14 @@ | |||
black: | |||
pipenv run black kosmorro _kosmorro setup.py | |||
pipenv run black kosmorro _kosmorro tests setup.py | |||
.PHONY: tests | |||
tests: | |||
@if [ "$${TEXLIVE_INSTALLED}" == "" ]; then \ | |||
echo "If you are running the tests locally and TeXLive is installed on your machine, you will need to set the TEXLIVE_INSTALLED environment variable."; \ | |||
echo; \ | |||
fi | |||
pipenv run python3 -m pytest tests/*.py | |||
.PHONY: build | |||
build: manpage | |||
@@ -6,6 +6,8 @@ verify_ssl = true | |||
[dev-packages] | |||
babel = "*" | |||
black = "*" | |||
pytest = "*" | |||
aurornis = "*" | |||
[packages] | |||
tabulate = "*" | |||
@@ -1,7 +1,7 @@ | |||
{ | |||
"_meta": { | |||
"hash": { | |||
"sha256": "c1f6551ee33e3015fa1aaa679059da0744c447948707b7e517cce926f336f6f9" | |||
"sha256": "3ff7290b32da63ca9585dbe947830ae1d1e4692f0ca9a0faeaa3601d7f9c4b8b" | |||
}, | |||
"pipfile-spec": 6, | |||
"requires": { | |||
@@ -59,7 +59,6 @@ | |||
"sha256:badca914580eb46385e7f7e4e426fea6de0a37b9e06bec252e481ae7ec287082", | |||
"sha256:d76a26c5118c4d96e264acc9e3242d72e1a2b92e739807b3b69d8d47684b6677" | |||
], | |||
"markers": "python_version >= '3.8'", | |||
"version": "==1.22.2" | |||
}, | |||
"python-dateutil": { | |||
@@ -109,7 +108,6 @@ | |||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", | |||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" | |||
], | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", | |||
"version": "==1.16.0" | |||
}, | |||
"skyfield": { | |||
@@ -123,7 +121,6 @@ | |||
"sha256:128d407e43a04be66c44b03914f9147b5e65b96078db776e6a4f5538ab0b74bf", | |||
"sha256:bd81bf9032d4833a766f4127e868d62674083ca2ccaea07e6d025e132c9c574e" | |||
], | |||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", | |||
"version": "==4.0.0" | |||
}, | |||
"tabulate": { | |||
@@ -143,6 +140,21 @@ | |||
} | |||
}, | |||
"develop": { | |||
"attrs": { | |||
"hashes": [ | |||
"sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", | |||
"sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" | |||
], | |||
"version": "==21.4.0" | |||
}, | |||
"aurornis": { | |||
"hashes": [ | |||
"sha256:660b57e9d1701d88fb7cc4af3118c927e9e001d2ab39cb145695eb8470f4642a", | |||
"sha256:bc68845be5cdf2d69d26c677214f7435365967b4a65dc3772ab05353b2136d95" | |||
], | |||
"index": "pypi", | |||
"version": "==1.2.0" | |||
}, | |||
"babel": { | |||
"hashes": [ | |||
"sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9", | |||
@@ -185,9 +197,15 @@ | |||
"sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1", | |||
"sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb" | |||
], | |||
"markers": "python_version >= '3.6'", | |||
"version": "==8.0.4" | |||
}, | |||
"iniconfig": { | |||
"hashes": [ | |||
"sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", | |||
"sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" | |||
], | |||
"version": "==1.1.1" | |||
}, | |||
"mypy-extensions": { | |||
"hashes": [ | |||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", | |||
@@ -195,6 +213,13 @@ | |||
], | |||
"version": "==0.4.3" | |||
}, | |||
"packaging": { | |||
"hashes": [ | |||
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", | |||
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" | |||
], | |||
"version": "==21.3" | |||
}, | |||
"pathspec": { | |||
"hashes": [ | |||
"sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a", | |||
@@ -207,9 +232,37 @@ | |||
"sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d", | |||
"sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227" | |||
], | |||
"markers": "python_version >= '3.7'", | |||
"version": "==2.5.1" | |||
}, | |||
"pluggy": { | |||
"hashes": [ | |||
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", | |||
"sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" | |||
], | |||
"version": "==1.0.0" | |||
}, | |||
"py": { | |||
"hashes": [ | |||
"sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", | |||
"sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" | |||
], | |||
"version": "==1.11.0" | |||
}, | |||
"pyparsing": { | |||
"hashes": [ | |||
"sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea", | |||
"sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484" | |||
], | |||
"version": "==3.0.7" | |||
}, | |||
"pytest": { | |||
"hashes": [ | |||
"sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db", | |||
"sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171" | |||
], | |||
"index": "pypi", | |||
"version": "==7.0.1" | |||
}, | |||
"pytz": { | |||
"hashes": [ | |||
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c", | |||
@@ -222,8 +275,15 @@ | |||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", | |||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" | |||
], | |||
"markers": "python_version >= '3.7'", | |||
"version": "==2.0.1" | |||
}, | |||
"typing-extensions": { | |||
"hashes": [ | |||
"sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", | |||
"sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" | |||
], | |||
"markers": "python_version < '3.10'", | |||
"version": "==4.1.1" | |||
} | |||
} | |||
} |
@@ -6,6 +6,7 @@ | |||
\usepackage{graphicx} | |||
\usepackage{hyperref} | |||
\usepackage{kosmorro} | |||
\usepackage{lmodern} | |||
\newcommand{\currentmoonphasetitle}{+++CURRENT-MOON-PHASE-TITLE+++} | |||
\newcommand{\ephemeridesobjecttitle}{+++EPHEMERIDES-OBJECT+++} | |||
@@ -8,7 +8,7 @@ msgid "" | |||
msgstr "" | |||
"Project-Id-Version: PROJECT VERSION\n" | |||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | |||
"POT-Creation-Date: 2022-02-04 13:30+0100\n" | |||
"POT-Creation-Date: 2022-02-16 13:58+0100\n" | |||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |||
"Language-Team: LANGUAGE <LL@li.org>\n" | |||
@@ -116,98 +116,98 @@ msgstr "" | |||
msgid "The date must be between {minimum_date} and {maximum_date}" | |||
msgstr "" | |||
#: _kosmorro/main.py:60 | |||
#: _kosmorro/main.py:62 | |||
msgid "" | |||
"Save the planet and paper!\n" | |||
"Consider printing your PDF document only if really necessary, and use the" | |||
" other side of the sheet." | |||
msgstr "" | |||
#: _kosmorro/main.py:69 | |||
#: _kosmorro/main.py:71 | |||
msgid "" | |||
"PDF output will not contain the ephemerides, because you didn't provide " | |||
"the observation coordinates." | |||
msgstr "" | |||
#: _kosmorro/main.py:114 | |||
#: _kosmorro/main.py:116 | |||
msgid "The file could not be saved in \"{path}\": {error}" | |||
msgstr "" | |||
#: _kosmorro/main.py:128 | |||
#: _kosmorro/main.py:130 | |||
msgid "Please provide a file path to export in this format (--output)." | |||
msgstr "" | |||
#: _kosmorro/main.py:161 | |||
#: _kosmorro/main.py:163 | |||
msgid "Moon phase can only be displayed between {min_date} and {max_date}" | |||
msgstr "" | |||
#: _kosmorro/main.py:200 | |||
#: _kosmorro/main.py:202 | |||
msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}" | |||
msgstr "" | |||
#: _kosmorro/main.py:213 | |||
#: _kosmorro/main.py:215 | |||
msgid "" | |||
"Compute the ephemerides and the events for a given date and a given " | |||
"position on Earth." | |||
msgstr "" | |||
#: _kosmorro/main.py:216 | |||
#: _kosmorro/main.py:218 | |||
msgid "" | |||
"By default, only the events will be computed for today ({date}).\n" | |||
"By default, only the events will be computed for today.\n" | |||
"To compute also the ephemerides, latitude and longitude arguments are " | |||
"needed." | |||
msgstr "" | |||
#: _kosmorro/main.py:230 | |||
#: _kosmorro/main.py:231 | |||
msgid "Show the program version" | |||
msgstr "" | |||
#: _kosmorro/main.py:238 | |||
#: _kosmorro/main.py:239 | |||
msgid "The format to output the information to" | |||
msgstr "" | |||
#: _kosmorro/main.py:245 | |||
#: _kosmorro/main.py:246 | |||
msgid "" | |||
"The observer's latitude on Earth. Can also be set in the " | |||
"KOSMORRO_LATITUDE environment variable." | |||
msgstr "" | |||
#: _kosmorro/main.py:255 | |||
#: _kosmorro/main.py:256 | |||
msgid "" | |||
"The observer's longitude on Earth. Can also be set in the " | |||
"KOSMORRO_LONGITUDE environment variable." | |||
msgstr "" | |||
#: _kosmorro/main.py:265 | |||
#: _kosmorro/main.py:266 | |||
msgid "" | |||
"The date for which the ephemerides must be calculated. Can be in the " | |||
"YYYY-MM-DD format or an interval in the \"[+-]YyMmDd\" format (with Y, M," | |||
" and D numbers). Defaults to today ({default_date})." | |||
" and D numbers). Defaults to current date." | |||
msgstr "" | |||
#: _kosmorro/main.py:276 | |||
#: _kosmorro/main.py:277 | |||
msgid "" | |||
"The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3). " | |||
"Can also be set in the KOSMORRO_TIMEZONE environment variable." | |||
msgstr "" | |||
#: _kosmorro/main.py:285 | |||
#: _kosmorro/main.py:286 | |||
msgid "Disable the colors in the console." | |||
msgstr "" | |||
#: _kosmorro/main.py:292 | |||
#: _kosmorro/main.py:293 | |||
msgid "" | |||
"A file to export the output to. If not given, the standard output is " | |||
"used. This argument is needed for PDF format." | |||
msgstr "" | |||
#: _kosmorro/main.py:301 | |||
#: _kosmorro/main.py:302 | |||
msgid "" | |||
"Do not generate a graph to represent the rise and set times in the PDF " | |||
"format." | |||
msgstr "" | |||
#: _kosmorro/main.py:309 | |||
#: _kosmorro/main.py:310 | |||
msgid "Show debugging messages" | |||
msgstr "" | |||
@@ -23,10 +23,10 @@ from kosmorrolib import Position, get_ephemerides, get_events, get_moon_phase | |||
from kosmorrolib.__version__ import __version__ as kosmorrolib_version | |||
from kosmorrolib.exceptions import OutOfRangeDateError | |||
from datetime import date | |||
from termcolor import colored | |||
from . import dumper, environment, debug | |||
from .date import parse_date | |||
from .utils import colored, set_colors_activated | |||
from .__version__ import __version__ as kosmorro_version | |||
from .exceptions import UnavailableFeatureError, OutOfRangeDateError as DateRangeError | |||
from _kosmorro.i18n.utils import _, SHORT_DATE_FORMAT | |||
@@ -39,6 +39,8 @@ def main(): | |||
debug.show_debug_messages = args.show_debug_messages | |||
output_format = args.format | |||
set_colors_activated(args.colors) | |||
if args.special_action is not None: | |||
return 0 if args.special_action() else 1 | |||
@@ -214,9 +216,8 @@ def get_args(output_formats: [str]): | |||
"Compute the ephemerides and the events for a given date and a given position on Earth." | |||
), | |||
epilog=_( | |||
"By default, only the events will be computed for today ({date}).\n" | |||
"To compute also the ephemerides, latitude and longitude arguments" | |||
" are needed." | |||
"By default, only the events will be computed for today.\n" | |||
"To compute also the ephemerides, latitude and longitude arguments are needed." | |||
).format(date=today.strftime(dumper.FULL_DATE_FORMAT)), | |||
) | |||
@@ -265,7 +266,7 @@ def get_args(output_formats: [str]): | |||
help=_( | |||
"The date for which the ephemerides must be calculated. Can be in the YYYY-MM-DD format " | |||
'or an interval in the "[+-]YyMmDd" format (with Y, M, and D numbers). ' | |||
"Defaults to today ({default_date})." | |||
"Defaults to current date." | |||
).format(default_date=today.strftime("%Y-%m-%d")), | |||
) | |||
parser.add_argument( | |||
@@ -0,0 +1,19 @@ | |||
#!/usr/bin/env python3 | |||
from termcolor import colored as do_color | |||
global _COLORS_ACTIVATED | |||
def set_colors_activated(activated: bool): | |||
global _COLORS_ACTIVATED | |||
_COLORS_ACTIVATED = activated | |||
def colored(text, color=None, on_color=None, attrs=None): | |||
"""Decorator to use colors only when they are activated""" | |||
if not _COLORS_ACTIVATED: | |||
return text | |||
return do_color(text, color, on_color, attrs) |
@@ -0,0 +1,52 @@ | |||
#!/usr/bin/env python3 | |||
from .utils import execute, KOSMORRO | |||
def test_with_date(): | |||
for arg in [["-d", "2020-01-27"], ["--date", "2020-01-27"], ["-d2020-01-27"]]: | |||
result = execute(KOSMORRO + arg) | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Monday January 27, 2020 | |||
Moon phase: New Moon | |||
First Quarter on Sunday February 02, 2020 at 01:41 | |||
Expected events: | |||
20:00 Venus and Neptune are in conjunction | |||
Note: All the hours are given in UTC. | |||
""" | |||
) | |||
def test_with_incorrect_date_values(): | |||
value = "yolo-yo-lo" | |||
for arg in [["-d", value], ["--date", value], [f"-d{value}"]]: | |||
result = execute(KOSMORRO + arg) | |||
assert not result.is_successful() | |||
assert ( | |||
result.stdout | |||
== f"The date {value} does not match the required YYYY-MM-DD format or the offset format.\n" | |||
) | |||
value = "2020-13-32" | |||
for arg in [["-d", value], ["--date", value], [f"-d{value}"]]: | |||
result = execute(KOSMORRO + arg) | |||
assert not result.is_successful() | |||
assert ( | |||
result.stdout == f"The date {value} is not valid: month must be in 1..12\n" | |||
) | |||
def test_with_out_of_range_dates(): | |||
for arg in [["-d", "1789-05-05"], ["-d", "3000-01-01"]]: | |||
result = execute(KOSMORRO + arg) | |||
assert not result.is_successful() | |||
assert ( | |||
result.stdout | |||
== "Moon phase can only be displayed between Aug 09, 1899 and Sep 26, 2053\n" | |||
) |
@@ -0,0 +1,85 @@ | |||
#!/usr/bin/env python3 | |||
from sys import version_info | |||
from .utils import ( | |||
execute, | |||
KOSMORRO, | |||
CURRENT_MOON_PHASE_PATTERN, | |||
NEXT_MOON_PHASE_PATTERN, | |||
) | |||
from datetime import date | |||
def test_run_without_argument(): | |||
result = execute(KOSMORRO) | |||
assert result.is_successful() | |||
stdout = result.stdout.split("\n") | |||
# It always starts with the current date, an empty line and the current and next Moon date: | |||
assert stdout[0] == date.today().strftime("%A %B %d, %Y") | |||
assert stdout[1] == "" | |||
assert CURRENT_MOON_PHASE_PATTERN.match(stdout[2]) | |||
assert NEXT_MOON_PHASE_PATTERN.match(stdout[3]) | |||
# It always finishes with an empty line, a note about UTC timezone and an empty line: | |||
assert stdout[-3] == "" | |||
assert stdout[-2] == "Note: All the hours are given in UTC." | |||
assert stdout[-1] == "" | |||
def test_help_message(): | |||
python_version = (version_info.major, version_info.minor) | |||
for arg in ["--help", "-h"]: | |||
result = execute(KOSMORRO + [arg]) | |||
assert result.is_successful() | |||
# Options header has changed from "optional arguments" to "options" in Python 3.10. | |||
options_header = ( | |||
"options" if python_version == (3, 10) else "optional arguments" | |||
) | |||
assert ( | |||
result.stdout | |||
== """usage: kosmorro [-h] [--version] [--format {text,json,pdf}] | |||
[--latitude LATITUDE] [--longitude LONGITUDE] [--date DATE] | |||
[--timezone TIMEZONE] [--no-colors] [--output OUTPUT] | |||
[--no-graph] [--debug] | |||
Compute the ephemerides and the events for a given date and a given position | |||
on Earth. | |||
%s: | |||
-h, --help show this help message and exit | |||
--version, -v Show the program version | |||
--format {text,json,pdf}, -f {text,json,pdf} | |||
The format to output the information to | |||
--latitude LATITUDE, -lat LATITUDE | |||
The observer's latitude on Earth. Can also be set in | |||
the KOSMORRO_LATITUDE environment variable. | |||
--longitude LONGITUDE, -lon LONGITUDE | |||
The observer's longitude on Earth. Can also be set in | |||
the KOSMORRO_LONGITUDE environment variable. | |||
--date DATE, -d DATE The date for which the ephemerides must be calculated. | |||
Can be in the YYYY-MM-DD format or an interval in the | |||
"[+-]YyMmDd" format (with Y, M, and D numbers). | |||
Defaults to current date. | |||
--timezone TIMEZONE, -t TIMEZONE | |||
The timezone to display the hours in (e.g. 2 for UTC+2 | |||
or -3 for UTC-3). Can also be set in the | |||
KOSMORRO_TIMEZONE environment variable. | |||
--no-colors Disable the colors in the console. | |||
--output OUTPUT, -o OUTPUT | |||
A file to export the output to. If not given, the | |||
standard output is used. This argument is needed for | |||
PDF format. | |||
--no-graph Do not generate a graph to represent the rise and set | |||
times in the PDF format. | |||
--debug Show debugging messages | |||
By default, only the events will be computed for today. To compute also the | |||
ephemerides, latitude and longitude arguments are needed. | |||
""" | |||
% options_header | |||
) |
@@ -0,0 +1,195 @@ | |||
#!/usr/bin/env python3 | |||
from .utils import ( | |||
execute, | |||
KOSMORRO, | |||
) | |||
import tempfile | |||
from os import path, environ | |||
from sys import platform | |||
def test_json_output(): | |||
result = execute( | |||
KOSMORRO | |||
+ ["--latitude=50.5876", "--longitude=3.0624", "-d2020-01-27", "--format=json"] | |||
) | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """{ | |||
"ephemerides": [ | |||
{ | |||
"object": { | |||
"identifier": "SUN", | |||
"type": "STAR", | |||
"radius": 696342 | |||
}, | |||
"rise_time": "2020-01-27T07:31:00", | |||
"culmination_time": "2020-01-27T12:01:00", | |||
"set_time": "2020-01-27T16:30:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "MOON", | |||
"type": "SATELLITE", | |||
"radius": 1737.4 | |||
}, | |||
"rise_time": "2020-01-27T09:06:00", | |||
"culmination_time": "2020-01-27T14:09:00", | |||
"set_time": "2020-01-27T19:13:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "MERCURY", | |||
"type": "PLANET", | |||
"radius": 2439.7 | |||
}, | |||
"rise_time": "2020-01-27T08:10:00", | |||
"culmination_time": "2020-01-27T12:49:00", | |||
"set_time": "2020-01-27T17:28:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "VENUS", | |||
"type": "PLANET", | |||
"radius": 6051.8 | |||
}, | |||
"rise_time": "2020-01-27T09:01:00", | |||
"culmination_time": "2020-01-27T14:35:00", | |||
"set_time": "2020-01-27T20:10:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "MARS", | |||
"type": "PLANET", | |||
"radius": 3396.2 | |||
}, | |||
"rise_time": "2020-01-27T04:19:00", | |||
"culmination_time": "2020-01-27T08:23:00", | |||
"set_time": "2020-01-27T12:28:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "JUPITER", | |||
"type": "PLANET", | |||
"radius": 71492 | |||
}, | |||
"rise_time": "2020-01-27T06:15:00", | |||
"culmination_time": "2020-01-27T10:18:00", | |||
"set_time": "2020-01-27T14:21:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "SATURN", | |||
"type": "PLANET", | |||
"radius": 60268 | |||
}, | |||
"rise_time": "2020-01-27T06:56:00", | |||
"culmination_time": "2020-01-27T11:09:00", | |||
"set_time": "2020-01-27T15:22:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "URANUS", | |||
"type": "PLANET", | |||
"radius": 25559 | |||
}, | |||
"rise_time": "2020-01-27T10:21:00", | |||
"culmination_time": "2020-01-27T17:25:00", | |||
"set_time": "2020-01-27T00:33:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "NEPTUNE", | |||
"type": "PLANET", | |||
"radius": 24764 | |||
}, | |||
"rise_time": "2020-01-27T09:01:00", | |||
"culmination_time": "2020-01-27T14:36:00", | |||
"set_time": "2020-01-27T20:10:00" | |||
}, | |||
{ | |||
"object": { | |||
"identifier": "PLUTO", | |||
"type": "PLANET", | |||
"radius": 1185 | |||
}, | |||
"rise_time": "2020-01-27T06:57:00", | |||
"culmination_time": "2020-01-27T11:04:00", | |||
"set_time": "2020-01-27T15:11:00" | |||
} | |||
], | |||
"moon_phase": { | |||
"phase": "NEW_MOON", | |||
"time": "2020-01-24T21:41:59.705921+00:00", | |||
"next": { | |||
"phase": "FIRST_QUARTER", | |||
"time": "2020-02-02T01:41:40.282275+00:00" | |||
} | |||
}, | |||
"events": [ | |||
{ | |||
"objects": [ | |||
{ | |||
"identifier": "VENUS", | |||
"type": "PLANET", | |||
"radius": 6051.8 | |||
}, | |||
{ | |||
"identifier": "NEPTUNE", | |||
"type": "PLANET", | |||
"radius": 24764 | |||
} | |||
], | |||
"EventType": "CONJUNCTION", | |||
"starts_at": "2020-01-27T20:00:23.242750+00:00", | |||
"ends_at": null, | |||
"details": null | |||
} | |||
] | |||
} | |||
""" | |||
) | |||
def test_pdf_output(): | |||
if platform != "linux": | |||
# Consider it works everywhere if it does at least on Linux | |||
return | |||
tmp_dir = tempfile.mkdtemp() | |||
result = execute( | |||
KOSMORRO | |||
+ [ | |||
"--latitude=50.5876", | |||
"--longitude=3.0624", | |||
"-d2020-01-27", | |||
"--format=pdf", | |||
f"--output={tmp_dir}/document.pdf", | |||
] | |||
) | |||
if environ.get("TEXLIVE_INSTALLED") is None: | |||
assert not result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Save the planet and paper! | |||
Consider printing your PDF document only if really necessary, and use the other side of the sheet. | |||
Building PDF was not possible, because some dependencies are not installed. | |||
Please look at the documentation at https://kosmorro.space/cli/generate-pdf/ for more information. | |||
""" | |||
) | |||
return | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Save the planet and paper! | |||
Consider printing your PDF document only if really necessary, and use the other side of the sheet. | |||
""" | |||
"" | |||
) | |||
assert path.exists(f"{tmp_dir}/document.pdf") |
@@ -0,0 +1,55 @@ | |||
#!/usr/bin/env python3 | |||
from .utils import ( | |||
execute, | |||
KOSMORRO, | |||
) | |||
def check_command_return(result): | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Monday January 27, 2020 | |||
Object Rise time Culmination time Set time | |||
-------- ----------- ------------------ ---------- | |||
Sun 07:31 12:01 16:30 | |||
Moon 09:06 14:09 19:13 | |||
Mercury 08:10 12:49 17:28 | |||
Venus 09:01 14:35 20:10 | |||
Mars 04:19 08:23 12:28 | |||
Jupiter 06:15 10:18 14:21 | |||
Saturn 06:56 11:09 15:22 | |||
Uranus 10:21 17:25 00:33 | |||
Neptune 09:01 14:36 20:10 | |||
Pluto 06:57 11:04 15:11 | |||
Moon phase: New Moon | |||
First Quarter on Sunday February 02, 2020 at 01:41 | |||
Expected events: | |||
20:00 Venus and Neptune are in conjunction | |||
Note: All the hours are given in UTC. | |||
""" | |||
) | |||
def test_with_position(): | |||
result = execute( | |||
KOSMORRO + ["--latitude=50.5876", "--longitude=3.0624", "-d2020-01-27"] | |||
) | |||
check_command_return(result) | |||
def test_with_position_env_vars(): | |||
check_command_return( | |||
execute( | |||
KOSMORRO + ["-d2020-01-27"], | |||
environment={ | |||
"KOSMORRO_LATITUDE": "50.5876", | |||
"KOSMORRO_LONGITUDE": "3.0624", | |||
}, | |||
) | |||
) |
@@ -0,0 +1,73 @@ | |||
#!/usr/bin/env python3 | |||
from .utils import ( | |||
execute, | |||
KOSMORRO, | |||
) | |||
def check_command_return_t_plus_one(result): | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Monday January 27, 2020 | |||
Moon phase: New Moon | |||
First Quarter on Sunday February 02, 2020 at 02:41 | |||
Expected events: | |||
21:00 Venus and Neptune are in conjunction | |||
Note: All the hours are given in the UTC+1 timezone. | |||
""" | |||
) | |||
def check_command_return_t_minus_one(result): | |||
assert result.is_successful() | |||
assert ( | |||
result.stdout | |||
== """Monday January 27, 2020 | |||
Moon phase: New Moon | |||
First Quarter on Sunday February 02, 2020 at 00:41 | |||
Expected events: | |||
19:00 Venus and Neptune are in conjunction | |||
Note: All the hours are given in the UTC-1 timezone. | |||
""" | |||
) | |||
def test_timezone(): | |||
check_command_return_t_plus_one( | |||
execute(KOSMORRO + ["--timezone=1", "-d2020-01-27"]) | |||
) | |||
check_command_return_t_minus_one( | |||
execute(KOSMORRO + ["--timezone=-1", "-d2020-01-27"]) | |||
) | |||
def test_timezone_with_env_var(): | |||
check_command_return_t_plus_one( | |||
execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "1"}) | |||
) | |||
check_command_return_t_minus_one( | |||
execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "-1"}) | |||
) | |||
# If both environment variable and argument are set, use argument: | |||
check_command_return_t_plus_one( | |||
execute( | |||
KOSMORRO + ["--timezone=1", "-d2020-01-27"], | |||
environment={"KOSMORRO_TIMEZONE": "-1"}, | |||
) | |||
) | |||
check_command_return_t_minus_one( | |||
execute( | |||
KOSMORRO + ["--timezone=-1", "-d2020-01-27"], | |||
environment={"KOSMORRO_TIMEZONE": "1"}, | |||
) | |||
) |
@@ -0,0 +1,50 @@ | |||
#!/usr/bin/env python3 | |||
import aurornis | |||
import re | |||
from os import environ | |||
from typing import Union | |||
DEFAULT_ENVIRONMENT = {"PATH": environ["PATH"]} | |||
KOSMORRO = ["./kosmorro", "--no-color"] | |||
CURRENT_MOON_PHASE_PATTERN = re.compile( | |||
r"^Moon phase: (" | |||
r"(New Moon)|(Waxing Crescent)|" | |||
r"(First Quarter)|(Waxing Gibbous)|" | |||
r"(Full Moon)|(Waning Gibbous)|" | |||
r"(Last Quarter)|(Waning Crescent)" | |||
r")$" | |||
) | |||
NEXT_MOON_PHASE_PATTERN = re.compile( | |||
r"^((New Moon)|(Waxing Crescent)|" | |||
r"(First Quarter)|(Waxing Gibbous)|" | |||
r"(Full Moon)|(Waning Gibbous)|" | |||
r"(Last Quarter)|(Waning Crescent)" | |||
r") " | |||
r"on ((Monday)|(Tuesday)|(Wednesday)|(Thursday)|(Friday)|(Saturday)|(Sunday)) " | |||
r"((January)|(February)|(March)|(April)|(May)|(June)|" | |||
r"(July)|(August)|(September)|(October)|(November)|(December)) " | |||
r"[0-9]{2}, [0-9]{4} at [0-9]{2}:[0-9]{2}$" | |||
) | |||
def execute( | |||
command, environment: {str: Union[int, str]} = None | |||
) -> aurornis.CommandResult: | |||
if environment is None: | |||
environment = DEFAULT_ENVIRONMENT | |||
else: | |||
for variable in DEFAULT_ENVIRONMENT: | |||
environment[variable] = DEFAULT_ENVIRONMENT[variable] | |||
return aurornis.run(command, environment) | |||
def assert_nb_lines(expected_nb: int, in_str: str): | |||
"""Check that the string has the specified number of lines and that the last one is empty.""" | |||
lines = in_str.split("\n") | |||
assert len(lines) == expected_nb | |||
assert lines[len(lines) - 1] == "" |