@@ -0,0 +1,32 @@ | |||
--- | |||
name: Bug report | |||
about: Create a report to help us improve | |||
title: '' | |||
labels: bug | |||
assignees: '' | |||
--- | |||
**Describe the bug** | |||
A clear and concise description of what the bug is. | |||
**To Reproduce** | |||
Steps to reproduce the behavior: | |||
1. Go to '...' | |||
2. Click on '....' | |||
3. Scroll down to '....' | |||
4. See error | |||
**Expected behavior** | |||
A clear and concise description of what you expected to happen. | |||
**Screenshots** | |||
If applicable, add screenshots to help explain your problem. | |||
**Your configuration (please complete the following information):** | |||
- OS: [e.g. iOS] | |||
- Python version: [e.g. 3.7.0] | |||
- Kosmorro version: [e.g. 1.0.0] | |||
**Additional context** | |||
Add any other context about the problem here. |
@@ -0,0 +1,20 @@ | |||
--- | |||
name: Event type proposal | |||
about: Suggest a type of event you'd like to see implemented in Kosmorro | |||
title: '' | |||
labels: "enhancement, \U0001F320 events" | |||
assignees: '' | |||
--- | |||
**Event type**: | |||
**Involved objects (check the boxes)**: | |||
- [ ] Sun | |||
- [ ] Earth's moon | |||
- [ ] Planets | |||
**Definition of the event:** | |||
<!-- Replace this comment with the official definition of the event type, with a link to its source. --> | |||
**Other useful information** (implementation proposal, etc): |
@@ -0,0 +1,20 @@ | |||
--- | |||
name: Feature request | |||
about: Suggest an idea for this project | |||
title: '' | |||
labels: enhancement | |||
assignees: '' | |||
--- | |||
**Is your feature request related to a problem? Please describe.** | |||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | |||
**Describe the solution you'd like** | |||
A clear and concise description of what you want to happen. | |||
**Describe alternatives you've considered** | |||
A clear and concise description of any alternative solutions or features you've considered. | |||
**Additional context** | |||
Add any other context or screenshots about the feature request here. |
@@ -0,0 +1,18 @@ | |||
| Q | A | |||
| -------------- | --- | |||
| Bug fix? | yes/no | |||
| New feature? | yes/no | |||
| Related issues | Fix #... <!-- prefix each issue number with "Fix #", if any --> | |||
| Has BC-break | yes/no | |||
| License | GNU AGPL-v3 | |||
**Checklist:** | |||
<!-- | |||
Leave the checklist as it when editing, and check the boxes once the PR created. | |||
--> | |||
- [ ] I have updated the manpages | |||
<!-- | |||
Replace this notice with a short README for your feature/bugfix. | |||
--> | |||
@@ -0,0 +1,15 @@ | |||
version: 2 | |||
updates: | |||
- package-ecosystem: pip | |||
directory: "/" | |||
schedule: | |||
interval: daily | |||
time: "04:00" | |||
open-pull-requests-limit: 10 | |||
target-branch: master | |||
reviewers: | |||
- Deuchnord | |||
commit-message: | |||
prefix: chore | |||
include: scope |
@@ -0,0 +1,66 @@ | |||
# For most projects, this workflow file will not need changing; you simply need | |||
# to commit it to your repository. | |||
# | |||
# You may wish to alter this file to override the set of languages analyzed, | |||
# or to provide custom queries or build logic. | |||
name: "CodeQL" | |||
on: | |||
push: | |||
branches: [master, features] | |||
pull_request: | |||
branches: [master, features] | |||
schedule: | |||
- cron: '0 8 * * 0' | |||
jobs: | |||
analyze: | |||
name: Analyze | |||
runs-on: ubuntu-latest | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
language: ['python'] | |||
steps: | |||
- name: Checkout repository | |||
uses: actions/checkout@v2 | |||
with: | |||
# We must fetch at least the immediate parents so that if this is | |||
# a pull request then we can checkout the head. | |||
fetch-depth: 2 | |||
# If this run was triggered by a pull request event, then checkout | |||
# the head of the pull request instead of the merge commit. | |||
- run: git checkout HEAD^2 | |||
if: ${{ github.event_name == 'pull_request' }} | |||
# Initializes the CodeQL tools for scanning. | |||
- name: Initialize CodeQL | |||
uses: github/codeql-action/init@v1 | |||
with: | |||
languages: ${{ matrix.language }} | |||
# If you wish to specify custom queries, you can do so here or in a config file. | |||
# By default, queries listed here will override any specified in a config file. | |||
# Prefix the list here with "+" to use these queries and those in the config file. | |||
# queries: ./path/to/local/query, your-org/your-repo/queries@main | |||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). | |||
# If this step fails, then you should remove it and run the build manually (see below) | |||
- name: Autobuild | |||
uses: github/codeql-action/autobuild@v1 | |||
# ℹ️ Command-line programs to run using the OS shell. | |||
# 📚 https://git.io/JvXDl | |||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines | |||
# and modify them (or add more) to build your code if your project | |||
# uses a compiled language | |||
#- run: | | |||
# make bootstrap | |||
# make release | |||
- name: Perform CodeQL Analysis | |||
uses: github/codeql-action/analyze@v1 |
@@ -0,0 +1,20 @@ | |||
name: Commit lint | |||
on: | |||
push: | |||
branches: [master, features] | |||
pull_request: | |||
branches: [master, features] | |||
jobs: | |||
commitlint: | |||
runs-on: ubuntu-latest | |||
steps: | |||
- uses: actions/checkout@v2 | |||
with: | |||
fetch-depth: 0 | |||
- uses: wagoid/commitlint-github-action@v2 | |||
with: | |||
helpURL: 'https://github.com/Kosmorro/kosmorro/blob/master/CONTRIBUTING.md#commiting' | |||
@@ -0,0 +1,26 @@ | |||
name: Python Lint | |||
on: | |||
push: | |||
branches: [master, features] | |||
pull_request: | |||
branches: [master, features] | |||
jobs: | |||
pylint: | |||
runs-on: ubuntu-latest | |||
name: PyLint | |||
steps: | |||
- uses: actions/checkout@v1 | |||
- name: Set up Python | |||
uses: actions/setup-python@v1 | |||
with: | |||
python-version: 3.9 | |||
- name: Install dependencies | |||
run: | | |||
pip install --upgrade pip pipenv | |||
pipenv sync -d | |||
- name: Lint | |||
run: | | |||
pipenv run pylint kosmorro *.py kosmorrolib/*.py |
@@ -0,0 +1,84 @@ | |||
name: Release Application | |||
on: | |||
push: | |||
tags: ['v*'] | |||
jobs: | |||
release: | |||
name: Create release | |||
runs-on: ubuntu-latest | |||
steps: | |||
- name: Checkout code | |||
uses: actions/checkout@v2 | |||
- name: Setup | |||
run: | | |||
sudo apt update | |||
sudo apt install ruby | |||
sudo gem install ronn | |||
- name: Prepare release | |||
id: prepare_release | |||
run: | | |||
changelog="$(git diff HEAD^ HEAD -- CHANGELOG.md | grep -E '\+[#*]' | sed 's/^+//')" | |||
changelog="${changelog//$'%'/'%25'}" | |||
changelog="${changelog//$'\n'/'%0A'}" | |||
changelog="${changelog//$'\r'/'%0D'}" | |||
echo "::set-output name=changelog::$changelog" | |||
- name: Build locales | |||
env: | |||
POEDITOR_API_ACCESS: ${{ secrets.POEDITOR_API_ACCESS }} | |||
run: | | |||
make POEDITOR_API_ACCESS="${POEDITOR_API_ACCESS}" i18n | |||
tar cf locales.tar.gz kosmorrolib/locales | |||
- name: Create release | |||
id: create_release | |||
uses: actions/create-release@v1 | |||
env: | |||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||
with: | |||
tag_name: ${{ github.ref }} | |||
release_name: Version ${{ github.ref }} | |||
draft: true | |||
prerelease: false | |||
body: | | |||
${{ steps.prepare_release.outputs.changelog }} | |||
- name: Upload locales | |||
id: upload-locales | |||
uses: actions/upload-release-asset@v1 | |||
env: | |||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||
with: | |||
upload_url: ${{ steps.create_release.outputs.upload_url }} | |||
asset_path: ./locales.tar.gz | |||
asset_name: locales.tar.gz | |||
asset_content_type: application/x-tar | |||
pip: | |||
name: Release to PyPI | |||
runs-on: ubuntu-latest | |||
steps: | |||
- uses: actions/checkout@v1 | |||
- name: Set up Python | |||
uses: actions/setup-python@v1 | |||
with: | |||
python-version: '3.7' | |||
- name: Setup environment | |||
run: | | |||
sudo apt update | |||
sudo apt install ruby | |||
sudo gem install ronn | |||
- name: Install dependencies | |||
run: | | |||
python -m pip install --upgrade pip | |||
pip install setuptools wheel twine skyfield numpy tabulate Babel requests | |||
- name: Build and publish | |||
env: | |||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} | |||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} | |||
POEDITOR_API_ACCESS: ${{ secrets.POEDITOR_API_ACCESS }} | |||
POEDITOR_PROJECT_ID: 306433 | |||
run: | | |||
make POEDITOR_API_ACCESS="${POEDITOR_API_ACCESS}" POEDITOR_PROJECT_ID="306433" build | |||
twine upload dist/* | |||
@@ -0,0 +1,46 @@ | |||
name: Stale | |||
on: | |||
schedule: | |||
- cron: '0 12 * * *' | |||
jobs: | |||
analyze: | |||
name: Analyze | |||
runs-on: ubuntu-latest | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
language: ['python'] | |||
steps: | |||
- name: Close Stale Issues | |||
uses: actions/stale@v3 | |||
with: | |||
start-date: 2021-02-01 | |||
days-before-stale: 60 | |||
days-before-issue-close: 7 | |||
days-before-pr-close: 14 | |||
stale-label: stale | |||
close-issue-label: wontfix | |||
close-pr-label: wontmerge | |||
exempt-issue-label: 'confirmed,enhancement' | |||
exempt-pr-label: 'on hold' | |||
stale-issue-message: > | |||
This issue has not been active since a lot of time. If you think it is still valid, feel free to reply with a simple comment. | |||
Without any update, I will close it in 7 days. | |||
stale-pr-message: > | |||
This pull request has not been active since a lot of time. If you're still working on it, please reply with a simple comment. | |||
Without any update, I will close it in 14 days. | |||
close-issue-message: > | |||
Closing this issue. | |||
If you think it should be considered, feel free to exhume it. | |||
close-pr-message: > | |||
Closing this PR, since it has not got activity for a while. | |||
If you're still working on it, feel free to reopen it. |
@@ -0,0 +1,77 @@ | |||
name: Unit tests | |||
on: | |||
push: | |||
branches: [master, features] | |||
pull_request: | |||
branches: [master, features] | |||
jobs: | |||
legacy-unit-tests: | |||
runs-on: ${{ matrix.os }} | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
os: | |||
- ubuntu-18.04 | |||
- ubuntu-20.04 | |||
- macos-10.15 | |||
- macos-11.0 | |||
python-version: | |||
- '3.7' | |||
- '3.8' | |||
- '3.9' | |||
name: Legacy unit tests (Python ${{ matrix.python-version }} on ${{ matrix.os }}) | |||
steps: | |||
- uses: actions/checkout@v1 | |||
- name: Set up Python | |||
uses: actions/setup-python@v1 | |||
with: | |||
python-version: ${{ matrix.python-version }} | |||
- name: Install dependencies | |||
run: | | |||
pip install --upgrade pip pipenv | |||
pipenv sync -d | |||
- name: Unit tests | |||
env: | |||
COVERALLS_PRO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} | |||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||
run: | | |||
make test | |||
pipenv run coveralls --service=github | |||
unit-tests: | |||
runs-on: ${{ matrix.os }} | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
os: | |||
- ubuntu-18.04 | |||
- ubuntu-20.04 | |||
- macos-10.15 | |||
- macos-11.0 | |||
python-version: | |||
- '3.7' | |||
- '3.8' | |||
- '3.9' | |||
- '3.10' | |||
name: Unit tests (Python ${{ matrix.python-version }} on ${{ matrix.os }}) | |||
steps: | |||
- uses: actions/checkout@v1 | |||
- name: Set up Python | |||
uses: actions/setup-python@v1 | |||
with: | |||
python-version: ${{ matrix.python-version }} | |||
- name: Install dependencies | |||
run: | | |||
pip install --upgrade pip pipenv | |||
pipenv sync -d | |||
- name: Unit tests | |||
env: | |||
COVERALLS_PRO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} | |||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |||
run: | | |||
make test | |||
pipenv run coveralls --service=github |
@@ -0,0 +1,2 @@ | |||
__pycache__ | |||
.coverage |
@@ -0,0 +1,50 @@ | |||
.PHONY: test | |||
tests: legacy-tests | |||
python3 tests.py | |||
legacy-tests: | |||
unset KOSMORRO_LATITUDE; \ | |||
unset KOSMORRO_LONGITUDE; \ | |||
unset KOSMORRO_TIMEZONE; \ | |||
LANG=C pipenv run python3 -m coverage run -m unittest tests | |||
.PHONY: build | |||
build: | |||
python3 setup.py sdist bdist_wheel | |||
env: | |||
@if [[ "$$RELEASE_NUMBER" == "" ]]; \ | |||
then echo "Missing environment variable: RELEASE_NUMBER."; \ | |||
echo 'Example: export RELEASE_NUMBER="1.0.0" (without the leading "v")'; \ | |||
exit 1; \ | |||
fi | |||
release: env | |||
@echo -e "\e[1mCreating release with version number \e[36m$$RELEASE_NUMBER\e[0m" | |||
@echo | |||
sed "s/^VERSION =.*/VERSION = '$$RELEASE_NUMBER'/g" kosmorrolib/version.py > version.py | |||
mv version.py kosmorrolib/version.py | |||
pipenv run python setup.py extract_messages --output-file=kosmorrolib/locales/messages.pot > /dev/null | |||
conventional-changelog -p angular -i CHANGELOG.md -s | |||
sed "0,/\\[\\]/s/\\[\\]/[v$$RELEASE_NUMBER]/g" CHANGELOG.md > /tmp/CHANGELOG.md | |||
sed -e "s/...v)/...v$$RELEASE_NUMBER)/" /tmp/CHANGELOG.md > CHANGELOG.md | |||
rm /tmp/CHANGELOG.md | |||
@echo | |||
@echo -e "\e[1mRelease \e[36m$$RELEASE_NUMBER\e[39m is ready to commit." | |||
@echo -e "Please review the changes, then invoke \e[33mmake finish-release\e[39m." | |||
finish-release: env | |||
git add CHANGELOG.md kosmorrolib/version.py kosmorrolib/locales/messages.pot | |||
git commit -m "build: bump version $$RELEASE_NUMBER" | |||
git tag "v$$RELEASE_NUMBER" | |||
git checkout features | |||
git merge master | |||
git checkout master | |||
@echo | |||
@echo -e "\e[1mVersion \e[36m$$RELEASE_NUMBER\e[39m successfully tagged!" | |||
@echo -e "Invoke \e[33mgit push origin master features v$$RELEASE_NUMBER\e[39m to finish." |
@@ -9,6 +9,7 @@ pylint = "*" | |||
babel = "*" | |||
unittest-data-provider = "*" | |||
coveralls = "*" | |||
parameterized = "*" | |||
[packages] | |||
skyfield = ">=1.32.0,<2.0.0" | |||
@@ -1,7 +1,7 @@ | |||
{ | |||
"_meta": { | |||
"hash": { | |||
"sha256": "05fc0ad542c6b81f02f9f1d6c4dbf8d2743ab07678c5c42aa3f7739c9aee7e36" | |||
"sha256": "6b2c66b95f3dd68b2c892979187a16d4e60114c973470258e2cf0c091bf75b8c" | |||
}, | |||
"pipfile-spec": 6, | |||
"requires": { | |||
@@ -69,39 +69,43 @@ | |||
}, | |||
"sgp4": { | |||
"hashes": [ | |||
"sha256:0864ba1062418b1b3e23e38e90032dd2c6be1f09b66c5026a18f8171548720a9", | |||
"sha256:1601f590950cd34ffc54c8c2811a228632d394c1e28a74054373638f7ead4801", | |||
"sha256:2a75446b7299217f7e66002677226dab4e41b1ad62ce7fb238c0947071655899", | |||
"sha256:2ad7a1c6dde04591a847c85397151e2adb458d889838a9e10177055bf373ec4a", | |||
"sha256:2c21fc1f47882136883390497f92afd387d79c35f23a534b652ae44e02da0518", | |||
"sha256:318309f4efa05361a64498ec0ac8e42a288439efe9cce6f823366c792d645e5c", | |||
"sha256:39acc3f6a5efb9ccf76e2d3fbe4b56c9c0de10db0d5d4cfdf421b0969bbaa1e6", | |||
"sha256:41bcb23f9fe020fa41d1729eebdff97144a6c884260ce50065e9201c45a989f8", | |||
"sha256:71db20e277b639c05287302521e7c56fd9f77d081bb7a5f251294c18af188e43", | |||
"sha256:7ea354472687dd54a40c0199238e6d22e4b86ab4d5eb356353be8559816f2754", | |||
"sha256:89b42139eefd741724b6e41b80510cdbd76b0bda8f85d6cb37564051d119c384", | |||
"sha256:93edb356869cd0c4c8b715523d26555c69bf81cebad23e5a31abdd5623e8819b", | |||
"sha256:967ac911e1ffbd795df97e89c17f0c07fb2c782ae16f02b2bed2f9ad834cc7f9", | |||
"sha256:b59509b488c0674c29806c181238a4d4868797122fb8e6681f7a3e5540a25403", | |||
"sha256:c76a8db1df422a8473a680fcfb3c6b4cfa0318cf0e7fac9ea1b898f898139b8f", | |||
"sha256:d33c185606eeeb7067ab3626eccdfdc4ea74346093fae646541ce8998c861540", | |||
"sha256:de3ddc1a8a01a8b9f67008d2da85376d59aebac464a54477e11f459119de5308", | |||
"sha256:df87ca4b6eac69b7ee2a6c0f7a3a29d9eda9785e21767e320d768f14170dd693", | |||
"sha256:e303c82a3fc51a73cf0f69ee3215b25c299d84fb766e522a71136ad6f9d3a6c0", | |||
"sha256:e576d9f4721d6380d6a7b9a9ca4dbc863ba9bd6f9242b4df12c0f68b50282f45", | |||
"sha256:f45d0a205fb18919ff83ca449d483e6306721365d5ea52d63f86d91b6ca967c0", | |||
"sha256:f5e6787d59683bfa5c9e1b88210d7bafc36b2fd8799438f30e1effa7da76764c", | |||
"sha256:f7fc5b55497d79fe638fe203bc634332cea3f466d3f08910a956f97477cdecbb", | |||
"sha256:fec4b597c4cc3dd330c9fd049c2d88ccea16aac474a57343082fa17fe1f84a05" | |||
"sha256:0bcc2e078d04a32f0db1278ecf434b85d51682ab0d6144490940f8a7479305c9", | |||
"sha256:15745e778634c7aea8a7d53f0108562ee80d3f9f4e2812ab1884b20f5fb1f995", | |||
"sha256:19cd0d8e2c0826819bd8e46ffcf7866d137078b4110603c644a9eb3427347fe6", | |||
"sha256:2cb573d4831db7ebfcd80442ba72cd3cbcae99d33bcc8ac298186bb358515cad", | |||
"sha256:465dc1ef603aac17f59a1b00716c1f0187b90eaf88ce14ff6b19a40c7dd4ad97", | |||
"sha256:6a7b9c109664284df3914e71bc9f773eda574d920763de5aac882e4e02002730", | |||
"sha256:786b8e674d23c9efa634b782dc9650970e8662c92bc7ba457296fad84afaf34a", | |||
"sha256:7b638875f7072926e57145537e831128a9bc6fed54c52fac8f5248fb775acc3e", | |||
"sha256:802db53c0bb3caf58f69e38fbb04d7648c98ec4b34e17b4c3e9f81308352a9e1", | |||
"sha256:850e16475a13cb11ec12c69c9b91d03e8f61461b083d9c6232d6119c2777a13f", | |||
"sha256:85fb39c28741270e1552bc90269e1d73d65eb1383696848100dd991622a87bf7", | |||
"sha256:8777dc09d027b4bd74675c91cf2284d79f800e11a22d0e18acca1611c49ae955", | |||
"sha256:968760092038672e6e0686b581090016d491bb373a41416d2898f334bfa831e8", | |||
"sha256:96b8359c520e0e66d6d9ec0d775c948401887b8b60ee0775d3b6ad465f13ba6a", | |||
"sha256:9a097c1f7f777bd3eb36578cc195253053794396e34e34d67e7e2c7fb6960fda", | |||
"sha256:9e6b0a476a9481aec19a23d69292b0009a465962decc15d22407a99aa4ad306a", | |||
"sha256:a427bb73931d91dcc5e8b8ca796636b862f172c471ebc000e43eed6d84e2ee72", | |||
"sha256:ae4d2401eff33a31737ec15a947a97bebe784701e064bb1d3096e05b068ca5b8", | |||
"sha256:b110b2e4cb9223913e48e1f1ed5783d52a29e97556fa89dfdef721d23d42b134", | |||
"sha256:bc17cc051246e21b0e63a536d236ddec6e27761107c7c3acfb6cdfe6c61627d8", | |||
"sha256:bc443f34a0a3d6c3b02701403c0cffc9af4a3e864f41168cd0fc6b416e27ff58", | |||
"sha256:c13f98a9227fb5a242c9ea17bcc701e220deb75c576d240581107d4e9d20ce80", | |||
"sha256:c3a17700f19c881cb816bc7998ccb32e07ad5dc1672affff90324e09f3262025", | |||
"sha256:c600da1a26257b733df9de5e8a916f06160b21f819f073cd56cbe7f3be709877", | |||
"sha256:cb07c686b2f5552f8048ad3cace371dac1e1a530fb1ce20031d1ef46854793c1", | |||
"sha256:cff9b03cf770753522face8be7fec52d4ba9eee0fe9d73d324fa0724343a97a5", | |||
"sha256:d31cd0347ddd3bbeee2c47867f0c8a8f9ed0d94815f902aa62aab676c740526b", | |||
"sha256:dafc9bf8d52d13d82490b27b1d93a7189e408e1b7b83a838db4f39b21718053e" | |||
], | |||
"version": "==2.17" | |||
"version": "==2.18" | |||
}, | |||
"six": { | |||
"hashes": [ | |||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", | |||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" | |||
], | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", | |||
"version": "==1.15.0" | |||
}, | |||
"skyfield": { | |||
@@ -115,11 +119,11 @@ | |||
"develop": { | |||
"astroid": { | |||
"hashes": [ | |||
"sha256:87ae7f2398b8a0ae5638ddecf9987f081b756e0e9fc071aeebdca525671fc4dc", | |||
"sha256:b31c92f545517dcc452f284bc9c044050862fbe6d93d2b3de4a215a6b384bf0d" | |||
"sha256:21d735aab248253531bb0f1e1e6d068f0ee23533e18ae8a6171ff892b98297cf", | |||
"sha256:cfc35498ee64017be059ceffab0a25bedf7548ab76f2bea691c5565896e7128d" | |||
], | |||
"markers": "python_version >= '3.6'", | |||
"version": "==2.5.0" | |||
"version": "==2.5.1" | |||
}, | |||
"babel": { | |||
"hashes": [ | |||
@@ -146,66 +150,69 @@ | |||
}, | |||
"coverage": { | |||
"hashes": [ | |||
"sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7", | |||
"sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5", | |||
"sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f", | |||
"sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde", | |||
"sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f", | |||
"sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f", | |||
"sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c", | |||
"sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66", | |||
"sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90", | |||
"sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337", | |||
"sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d", | |||
"sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4", | |||
"sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409", | |||
"sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37", | |||
"sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1", | |||
"sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247", | |||
"sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39", | |||
"sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c", | |||
"sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994", | |||
"sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c", | |||
"sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb", | |||
"sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc", | |||
"sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f", | |||
"sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca", | |||
"sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135", | |||
"sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3", | |||
"sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339", | |||
"sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9", | |||
"sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9", | |||
"sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af", | |||
"sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370", | |||
"sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19", | |||
"sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3", | |||
"sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44", | |||
"sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3", | |||
"sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a", | |||
"sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c", | |||
"sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b", | |||
"sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9", | |||
"sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8", | |||
"sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22", | |||
"sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f", | |||
"sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345", | |||
"sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880", | |||
"sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0", | |||
"sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b", | |||
"sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec", | |||
"sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3", | |||
"sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786" | |||
"sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c", | |||
"sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6", | |||
"sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45", | |||
"sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a", | |||
"sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03", | |||
"sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529", | |||
"sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a", | |||
"sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a", | |||
"sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2", | |||
"sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6", | |||
"sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759", | |||
"sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53", | |||
"sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a", | |||
"sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4", | |||
"sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff", | |||
"sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502", | |||
"sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793", | |||
"sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb", | |||
"sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905", | |||
"sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821", | |||
"sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b", | |||
"sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81", | |||
"sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0", | |||
"sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b", | |||
"sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3", | |||
"sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184", | |||
"sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701", | |||
"sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a", | |||
"sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82", | |||
"sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638", | |||
"sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5", | |||
"sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083", | |||
"sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6", | |||
"sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90", | |||
"sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465", | |||
"sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a", | |||
"sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3", | |||
"sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e", | |||
"sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066", | |||
"sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf", | |||
"sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b", | |||
"sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae", | |||
"sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669", | |||
"sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873", | |||
"sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b", | |||
"sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6", | |||
"sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb", | |||
"sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160", | |||
"sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c", | |||
"sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079", | |||
"sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d", | |||
"sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6" | |||
], | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", | |||
"version": "==5.4" | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'", | |||
"version": "==5.5" | |||
}, | |||
"coveralls": { | |||
"hashes": [ | |||
"sha256:5399c0565ab822a70a477f7031f6c88a9dd196b3de2877b3facb43b51bd13434", | |||
"sha256:f8384968c57dee4b7133ae701ecdad88e85e30597d496dcba0d7fbb470dca41f" | |||
"sha256:7bd173b3425733661ba3063c88f180127cc2b20e9740686f86d2622b31b41385", | |||
"sha256:cbb942ae5ef3d2b55388cb5b43e93a269544911535f1e750e1c656aef019ce60" | |||
], | |||
"index": "pypi", | |||
"version": "==3.0.0" | |||
"version": "==3.0.1" | |||
}, | |||
"docopt": { | |||
"hashes": [ | |||
@@ -226,7 +233,7 @@ | |||
"sha256:c729845434366216d320e936b8ad6f9d681aab72dc7cbc2d51bedc3582f3ad1e", | |||
"sha256:fff4f0c04e1825522ce6949973e83110a6e907750cd92d128b0d14aaaadbffdc" | |||
], | |||
"markers": "python_version >= '3.6' and python_version < '4'", | |||
"markers": "python_version >= '3.6' and python_version < '4.0'", | |||
"version": "==5.7.0" | |||
}, | |||
"lazy-object-proxy": { | |||
@@ -266,13 +273,21 @@ | |||
], | |||
"version": "==0.6.1" | |||
}, | |||
"parameterized": { | |||
"hashes": [ | |||
"sha256:41bbff37d6186430f77f900d777e5bb6a24928a1c46fb1de692f8b52b8833b5c", | |||
"sha256:9cbb0b69a03e8695d68b3399a8a5825200976536fe1cb79db60ed6a4c8c9efe9" | |||
], | |||
"index": "pypi", | |||
"version": "==0.8.1" | |||
}, | |||
"pylint": { | |||
"hashes": [ | |||
"sha256:81ce108f6342421169ea039ff1f528208c99d2e5a9c4ca95cfc5291be6dfd982", | |||
"sha256:a251b238db462b71d25948f940568bb5b3ae0e37dbaa05e10523f54f83e6cc7e" | |||
"sha256:0e21d3b80b96740909d77206d741aa3ce0b06b41be375d92e1f3244a274c1f8a", | |||
"sha256:d09b0b07ba06bcdff463958f53f23df25e740ecd81895f7d2699ec04bbd8dc3b" | |||
], | |||
"index": "pypi", | |||
"version": "==2.7.1" | |||
"version": "==2.7.2" | |||
}, | |||
"pylintfileheader": { | |||
"hashes": [ | |||
@@ -302,7 +317,7 @@ | |||
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", | |||
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" | |||
], | |||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", | |||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", | |||
"version": "==0.10.2" | |||
}, | |||
"unittest-data-provider": { | |||
@@ -317,7 +332,7 @@ | |||
"sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", | |||
"sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" | |||
], | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", | |||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4.0'", | |||
"version": "==1.26.3" | |||
}, | |||
"wrapt": { | |||
@@ -33,7 +33,7 @@ from .exceptions import OutOfRangeDateError | |||
RISEN_ANGLE = -0.8333 | |||
def _get_skyfield_to_moon_phase(times: [Time], vals: [int], now: Time) -> Union[MoonPhaseType, None]: | |||
def _get_skyfield_to_moon_phase(times: [Time], vals: [int], now: Time) -> Union[MoonPhase, None]: | |||
tomorrow = get_timescale().utc(now.utc_datetime().year, now.utc_datetime().month, now.utc_datetime().day + 1) | |||
phases = list(MoonPhaseType) | |||
@@ -65,12 +65,12 @@ def _get_skyfield_to_moon_phase(times: [Time], vals: [int], now: Time) -> Union[ | |||
next_phase_time = times[j] | |||
break | |||
return MoonPhaseType(current_phase, | |||
return MoonPhase(current_phase, | |||
current_phase_time.utc_datetime() if current_phase_time is not None else None, | |||
next_phase_time.utc_datetime() if next_phase_time is not None else None) | |||
def get_moon_phase(compute_date: datetime.date, timezone: int = 0) -> MoonPhaseType: | |||
def get_moon_phase(compute_date: datetime.date, timezone: int = 0) -> MoonPhase: | |||
earth = get_skf_objects()['earth'] | |||
moon = get_skf_objects()['moon'] | |||
sun = get_skf_objects()['sun'] | |||
@@ -181,7 +181,7 @@ def get_events(date: date_type, timezone: int = 0) -> [Event]: | |||
"""Calculate and return a list of events for the given date, adjusted to the given timezone if any. | |||
Find events that happen on April 4th, 2020 (show hours in UTC): | |||
>>> get_events(date_type(2020, 4, 4)) | |||
[<Event type=CONJUNCTION objects=[<Object type=planet name=Mercury />, <Object type=planet name=Neptune />] start=2020-04-04 01:14:39.063308+00:00 end=None details=None />] | |||
@@ -3,4 +3,4 @@ import doctest | |||
from kosmorrolib import * | |||
for module in [events]: | |||
doctest.testmod(module) | |||
doctest.testmod(module, verbose=True) |
@@ -0,0 +1,6 @@ | |||
from .core import * | |||
from .data import * | |||
from .ephemerides import * | |||
from .events import * | |||
from .testutils import * | |||
from .dateutil import * |
@@ -0,0 +1,39 @@ | |||
import unittest | |||
import os | |||
import kosmorrolib.core as core | |||
from datetime import date | |||
from dateutil.relativedelta import relativedelta | |||
class CoreTestCase(unittest.TestCase): | |||
def test_flatten_list(self): | |||
self.assertEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], core.flatten_list([0, 1, 2, [3, 4, [5, 6], 7], 8, [9]])) | |||
def test_get_env(self): | |||
self.assertEqual(0, len(core.get_env())) | |||
os.environ['SOME_RANDOM_VAR'] = 'an awesome value' | |||
self.assertEqual(0, len(core.get_env())) | |||
os.environ['KOSMORRO_GREAT_VARIABLE'] = 'value' | |||
env = core.get_env() | |||
self.assertEqual(1, len(env)) | |||
self.assertEqual('value', env.great_variable) | |||
os.environ['KOSMORRO_ANOTHER_VARIABLE'] = 'another value' | |||
env = core.get_env() | |||
self.assertEqual(2, len(env)) | |||
self.assertEqual('value', env.great_variable) | |||
self.assertEqual('another value', env.another_variable) | |||
self.assertEqual("{'great_variable': 'value', 'another_variable': 'another value'}", str(env)) | |||
def test_date_arg_parsing(self): | |||
self.assertEqual(core.get_date("+1y 2m3d"), date.today() + relativedelta(years=1, months=2, days=3)) | |||
self.assertEqual(core.get_date("-1y2d"), date.today() - relativedelta(years=1, days=2)) | |||
self.assertEqual(core.get_date("1111-11-13"), date(1111, 11, 13)) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,17 @@ | |||
import unittest | |||
from kosmorrolib import data, core | |||
class DataTestCase(unittest.TestCase): | |||
def test_object_radius_must_be_set_to_get_apparent_radius(self): | |||
o = data.Planet('Saturn', 'SATURN') | |||
with self.assertRaises(ValueError) as context: | |||
o.get_apparent_radius(core.get_timescale().now(), core.get_skf_objects()['earth']) | |||
self.assertEqual(('Missing radius for Saturn object',), context.exception.args) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,24 @@ | |||
import unittest | |||
from kosmorrolib import dateutil | |||
from datetime import datetime | |||
class DateUtilTestCase(unittest.TestCase): | |||
def test_translate_to_timezone(self): | |||
date = dateutil.translate_to_timezone(datetime(2020, 6, 9, 4), to_tz=-2) | |||
self.assertEqual(2, date.hour) | |||
date = dateutil.translate_to_timezone(datetime(2020, 6, 9, 0), to_tz=2) | |||
self.assertEqual(2, date.hour) | |||
date = dateutil.translate_to_timezone(datetime(2020, 6, 9, 8), to_tz=2, from_tz=6) | |||
self.assertEqual(4, date.hour) | |||
date = dateutil.translate_to_timezone(datetime(2020, 6, 9, 1), to_tz=0, from_tz=2) | |||
self.assertEqual(8, date.day) | |||
self.assertEqual(23, date.hour) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,124 @@ | |||
import unittest | |||
from kosmorrolib.enum import MoonPhaseType | |||
from .testutils import expect_assertions | |||
from kosmorrolib import ephemerides | |||
from kosmorrolib.data import EARTH, Position, MoonPhase | |||
from datetime import date | |||
from kosmorrolib.exceptions import OutOfRangeDateError | |||
class EphemeridesTestCase(unittest.TestCase): | |||
def test_get_ephemerides_for_aster_returns_correct_hours(self): | |||
position = Position(0, 0, EARTH) | |||
eph = ephemerides.get_ephemerides(date=date(2019, 11, 18), | |||
position=position) | |||
@expect_assertions(self.assertRegex, num=3) | |||
def do_assertions(assert_regex): | |||
for ephemeris in eph: | |||
if ephemeris.object.skyfield_name == 'SUN': | |||
assert_regex(ephemeris.rise_time.isoformat(), '^2019-11-18T05:41:') | |||
assert_regex(ephemeris.culmination_time.isoformat(), '^2019-11-18T11:45:') | |||
assert_regex(ephemeris.set_time.isoformat(), '^2019-11-18T17:48:') | |||
break | |||
do_assertions() | |||
################################################################################################################### | |||
### MOON PHASE TESTS ### | |||
################################################################################################################### | |||
def test_moon_phase_new_moon(self): | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 25)) | |||
self.assertEqual(MoonPhaseType.WANING_CRESCENT, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 26)) | |||
self.assertEqual(MoonPhaseType.NEW_MOON, phase.phase_type) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-12-04T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 27)) | |||
self.assertEqual(MoonPhaseType.WAXING_CRESCENT, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-12-04T') | |||
def test_moon_phase_first_crescent(self): | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 3)) | |||
self.assertEqual(MoonPhaseType.WAXING_CRESCENT, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-04T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 4)) | |||
self.assertEqual(MoonPhaseType.FIRST_QUARTER, phase.phase_type) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 5)) | |||
self.assertEqual(MoonPhaseType.WAXING_GIBBOUS, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
def test_moon_phase_full_moon(self): | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 11)) | |||
self.assertEqual(MoonPhaseType.WAXING_GIBBOUS, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 12)) | |||
self.assertEqual(MoonPhaseType.FULL_MOON, phase.phase_type) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 13)) | |||
self.assertEqual(MoonPhaseType.WANING_GIBBOUS, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
def test_moon_phase_last_quarter(self): | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 18)) | |||
self.assertEqual(MoonPhaseType.WANING_GIBBOUS, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 19)) | |||
self.assertEqual(MoonPhaseType.LAST_QUARTER, phase.phase_type) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||
phase = ephemerides.get_moon_phase(date(2019, 11, 20)) | |||
self.assertEqual(MoonPhaseType.WANING_CRESCENT, phase.phase_type) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||
def test_moon_phase_prediction(self): | |||
phase = MoonPhase(MoonPhaseType.NEW_MOON, None, None) | |||
self.assertEqual(MoonPhaseType.FIRST_QUARTER, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.WAXING_CRESCENT, None, None) | |||
self.assertEqual(MoonPhaseType.FIRST_QUARTER, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.FIRST_QUARTER, None, None) | |||
self.assertEqual(MoonPhaseType.FULL_MOON, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.WAXING_GIBBOUS, None, None) | |||
self.assertEqual(MoonPhaseType.FULL_MOON, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.FULL_MOON, None, None) | |||
self.assertEqual(MoonPhaseType.LAST_QUARTER, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.WANING_GIBBOUS, None, None) | |||
self.assertEqual(MoonPhaseType.LAST_QUARTER, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.LAST_QUARTER, None, None) | |||
self.assertEqual(MoonPhaseType.NEW_MOON, phase.get_next_phase()) | |||
phase = MoonPhase(MoonPhaseType.WANING_CRESCENT, None, None) | |||
self.assertEqual(MoonPhaseType.NEW_MOON, phase.get_next_phase()) | |||
def test_get_ephemerides_raises_exception_on_out_of_date_range(self): | |||
with self.assertRaises(OutOfRangeDateError): | |||
ephemerides.get_ephemerides(date(1789, 5, 5), Position(0, 0, EARTH)) | |||
def test_get_moon_phase_raises_exception_on_out_of_date_range(self): | |||
with self.assertRaises(OutOfRangeDateError): | |||
ephemerides.get_moon_phase(date(1789, 5, 5)) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,83 @@ | |||
import unittest | |||
from datetime import date, datetime | |||
from parameterized import parameterized | |||
from kosmorrolib import events | |||
from kosmorrolib.data import Event, ASTERS | |||
from kosmorrolib.enum import EventType | |||
from kosmorrolib.exceptions import OutOfRangeDateError | |||
EXPECTED_EVENTS = [ | |||
(date(2020, 2, 7), []), | |||
(date(2020, 10, 13), [Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2020, 10, 13, 23, 25))]), | |||
(date(2022, 12, 8), | |||
[Event(EventType.CONJUNCTION, [ASTERS[1], ASTERS[4]], datetime(2022, 12, 8, 4, 18)), | |||
Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2022, 12, 8, 5, 41))]), | |||
(date(2025, 1, 16), [Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2025, 1, 16, 2, 38))]), | |||
(date(2027, 2, 19), [Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2027, 2, 19, 7, 38)), | |||
Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2027, 2, 19, 15, 50))]), | |||
(date(2020, 1, 2), [Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 1, 2, 1, 32)), | |||
Event(EventType.CONJUNCTION, [ASTERS[2], ASTERS[5]], | |||
datetime(2020, 1, 2, 16, 41))]), | |||
(date(2020, 1, 12), | |||
[Event(EventType.CONJUNCTION, [ASTERS[2], ASTERS[6]], datetime(2020, 1, 12, 9, 51)), | |||
Event(EventType.CONJUNCTION, [ASTERS[2], ASTERS[9]], datetime(2020, 1, 12, 10, 13)), | |||
Event(EventType.CONJUNCTION, [ASTERS[6], ASTERS[9]], datetime(2020, 1, 12, 16, 57))]), | |||
(date(2020, 2, 10), | |||
[Event(EventType.MAXIMAL_ELONGATION, [ASTERS[2]], datetime(2020, 2, 10, 13, 46), details='18.2°'), | |||
Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2020, 2, 10, 20, 34))]), | |||
(date(2020, 3, 24), | |||
[Event(EventType.MAXIMAL_ELONGATION, [ASTERS[2]], datetime(2020, 3, 24, 1, 56), details='27.8°'), | |||
Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 3, 24, 15, 39)), | |||
Event(EventType.MAXIMAL_ELONGATION, [ASTERS[3]], datetime(2020, 3, 24, 21, 58), | |||
details='46.1°')]), | |||
(date(2005, 6, 16), | |||
[Event(EventType.OCCULTATION, [ASTERS[1], ASTERS[5]], datetime(2005, 6, 16, 6, 31))]), | |||
(date(2020, 4, 7), [Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2020, 4, 7, 18, 14))]), | |||
(date(2020, 1, 29), [Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 1, 29, 21, 32))]) | |||
] | |||
class EventTestCase(unittest.TestCase): | |||
def setUp(self) -> None: | |||
self.maxDiff = None | |||
@parameterized.expand(EXPECTED_EVENTS) | |||
def test_search_events(self, d: date, expected_events: [Event]): | |||
actual_events = events.get_events(d) | |||
self.assertEqual(len(expected_events), len(actual_events), | |||
'Expected %d elements, got %d for date %s.\n%s' % (len(expected_events), | |||
len(actual_events), | |||
d.isoformat(), | |||
actual_events)) | |||
for i, expected_event in enumerate(expected_events): | |||
actual_event = actual_events[i] | |||
# Remove unnecessary precision (seconds and microseconds) | |||
actual_event.start_time = datetime(actual_event.start_time.year, | |||
actual_event.start_time.month, | |||
actual_event.start_time.day, | |||
actual_event.start_time.hour, | |||
actual_event.start_time.minute) | |||
self.assertEqual(expected_event.__dict__, actual_event.__dict__) | |||
def test_get_events_raises_exception_on_out_of_date_range(self): | |||
with self.assertRaises(OutOfRangeDateError): | |||
events.get_events(date(1789, 5, 5)) | |||
if __name__ == '__main__': | |||
unittest.main() |
@@ -0,0 +1,48 @@ | |||
import functools | |||
from unittest import mock | |||
def expect_assertions(assert_fun, num=1): | |||
"""Asserts that an assertion function is called as expected. | |||
This is very useful when the assertions are in loops. | |||
To use it, create a nested function in the the tests function. | |||
The nested function will receive as parameter the mocked assertion function to use in place of the original one. | |||
Finally, run the nested function. | |||
Example of use: | |||
>>> # the function we tests: | |||
>>> def my_sum_function(n, m): | |||
>>> # some code here | |||
>>> pass | |||
>>> # The unit tests: | |||
>>> def test_sum(self): | |||
>>> @expect_assertions(self.assertEqual, num=10): | |||
>>> def make_assertions(assert_equal): | |||
>>> for i in range (-5, 5): | |||
>>> for j in range(-5, 5): | |||
>>> assert_equal(i + j, my_sum_function(i, j) | |||
>>> | |||
>>> make_assertions() # You don't need to give any parameter, the decorator does it for you. | |||
:param assert_fun: the assertion function to tests | |||
:param num: the number of times the assertion function is expected to be called | |||
""" | |||
assert_fun_mock = mock.Mock(side_effect=assert_fun) | |||
def fun_decorator(fun): | |||
@functools.wraps(fun) | |||
def sniff_function(): | |||
fun(assert_fun_mock) | |||
count = assert_fun_mock.call_count | |||
if count != num: | |||
raise AssertionError('Expected %d call(s) to function %s but called %d time(s).' % (num, | |||
assert_fun.__name__, | |||
count)) | |||
return sniff_function | |||
return fun_decorator |