diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml
index 39cf6ba..ea2e9da 100644
--- a/.github/workflows/pythonpublish.yml
+++ b/.github/workflows/pythonpublish.yml
@@ -8,11 +8,11 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
with:
fetch-depth: '0'
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
diff --git a/.github/workflows/scheduled_unittests.yml b/.github/workflows/scheduled_unittests.yml
index e4e8774..9a01051 100644
--- a/.github/workflows/scheduled_unittests.yml
+++ b/.github/workflows/scheduled_unittests.yml
@@ -20,7 +20,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@master
with:
- python-version: 3.9
+ python-version: 3.10
- name: Install dependencies
run: |
diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml
index 5d57fcd..2ec52b1 100644
--- a/.github/workflows/unittests.yml
+++ b/.github/workflows/unittests.yml
@@ -5,11 +5,11 @@ jobs:
name: Run unit tests with codecov upload
runs-on: ${{ matrix.os }}
env:
- USING_COVERAGE: '3.7'
+ USING_COVERAGE: '3.10'
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- python-version: [3.7, 3.8, 3.9, "3.10"]
+ python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@master
diff --git a/.github/workflows/unittests_codecov.yml b/.github/workflows/unittests_codecov.yml
index b3a9d07..1e07c34 100644
--- a/.github/workflows/unittests_codecov.yml
+++ b/.github/workflows/unittests_codecov.yml
@@ -13,11 +13,11 @@ jobs:
name: Run unit tests with codecov upload
runs-on: ${{ matrix.os }}
env:
- USING_COVERAGE: '3.7'
+ USING_COVERAGE: '3.10'
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- python-version: [3.7, 3.8, 3.9, "3.10"]
+ python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@master
diff --git a/mkdocs_git_revision_date_localized_plugin/dates.py b/mkdocs_git_revision_date_localized_plugin/dates.py
new file mode 100644
index 0000000..17266fd
--- /dev/null
+++ b/mkdocs_git_revision_date_localized_plugin/dates.py
@@ -0,0 +1,47 @@
+
+from babel.dates import format_date, get_timezone
+
+from datetime import datetime, timezone
+from typing import Any, Dict
+
+
+def get_date_formats(
+ unix_timestamp: float,
+ locale: str = "en",
+ time_zone: str = "UTC",
+ custom_format: str = "%d. %B %Y"
+) -> Dict[str, Any]:
+ """
+ Calculate different date formats / types.
+
+ Args:
+ unix_timestamp (float): A timestamp in seconds since 1970. Assumes UTC.
+ locale (str): Locale code of language to use. Defaults to 'en'.
+ time_zone (str): Timezone database name (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+ custom_format (str): strftime format specifier for the 'custom' type
+
+ Returns:
+ dict: Different date formats.
+ """
+ assert time_zone is not None
+ assert locale is not None
+
+ utc_revision_date = datetime.fromtimestamp(int(unix_timestamp), tz=timezone.utc)
+ loc_revision_date = utc_revision_date.replace(
+ tzinfo=get_timezone("UTC")
+ ).astimezone(get_timezone(time_zone))
+
+ return {
+ "date": format_date(loc_revision_date, format="long", locale=locale),
+ "datetime": " ".join(
+ [
+ format_date(loc_revision_date, format="long", locale=locale),
+ loc_revision_date.strftime("%H:%M:%S"),
+ ]
+ ),
+ "iso_date": loc_revision_date.strftime("%Y-%m-%d"),
+ "iso_datetime": loc_revision_date.strftime("%Y-%m-%d %H:%M:%S"),
+ "timeago": '' % (loc_revision_date.isoformat(), locale),
+ "custom": loc_revision_date.strftime(custom_format),
+ }
+
\ No newline at end of file
diff --git a/mkdocs_git_revision_date_localized_plugin/util.py b/mkdocs_git_revision_date_localized_plugin/util.py
index 370a3d3..1cbb474 100644
--- a/mkdocs_git_revision_date_localized_plugin/util.py
+++ b/mkdocs_git_revision_date_localized_plugin/util.py
@@ -2,11 +2,11 @@
import logging
import os
import time
-from datetime import datetime
from mkdocs_git_revision_date_localized_plugin.ci import raise_ci_warnings
+from mkdocs_git_revision_date_localized_plugin.dates import get_date_formats
+
-from babel.dates import format_date, get_timezone
from git import (
Repo,
Git,
@@ -16,7 +16,7 @@
NoSuchPathError,
)
-from typing import Any, Dict
+from typing import Dict
logger = logging.getLogger("mkdocs.plugins")
@@ -44,43 +44,6 @@ def _get_repo(self, path: str) -> Git:
return self.repo_cache[path]
- @staticmethod
- def _date_formats(
- unix_timestamp: float, locale: str = "en", time_zone: str = "UTC", custom_format: str = "%d. %B %Y"
- ) -> Dict[str, Any]:
- """
- Calculate different date formats / types.
-
- Args:
- unix_timestamp (float): A timestamp in seconds since 1970.
- locale (str): Locale code of language to use. Defaults to 'en'.
- time_zone (str): Timezone database name (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- custom_format (str): strftime format specifier for the 'custom' type
-
- Returns:
- dict: Different date formats.
- """
- assert time_zone is not None
- assert locale is not None
-
- utc_revision_date = datetime.utcfromtimestamp(int(unix_timestamp))
- loc_revision_date = utc_revision_date.replace(
- tzinfo=get_timezone("UTC")
- ).astimezone(get_timezone(time_zone))
-
- return {
- "date": format_date(loc_revision_date, format="long", locale=locale),
- "datetime": " ".join(
- [
- format_date(loc_revision_date, format="long", locale=locale),
- loc_revision_date.strftime("%H:%M:%S"),
- ]
- ),
- "iso_date": loc_revision_date.strftime("%Y-%m-%d"),
- "iso_datetime": loc_revision_date.strftime("%Y-%m-%d %H:%M:%S"),
- "timeago": '' % (loc_revision_date.isoformat(), locale),
- "custom": loc_revision_date.strftime(custom_format),
- }
def get_git_commit_timestamp(
self,
@@ -201,7 +164,7 @@ def get_date_formats_for_timestamp(
Returns:
dict: Localized date variants.
"""
- date_formats = self._date_formats(
+ date_formats = get_date_formats(
unix_timestamp=commit_timestamp,
time_zone=self.config.get("timezone"),
locale=locale,
diff --git a/tests/fixtures/i18n/mkdocs.yml b/tests/fixtures/i18n/mkdocs.yml
index f15690b..f3e44c7 100644
--- a/tests/fixtures/i18n/mkdocs.yml
+++ b/tests/fixtures/i18n/mkdocs.yml
@@ -22,22 +22,13 @@ markdown_extensions:
plugins:
- search
- i18n:
- default_language: !ENV [DEFAULT_LANGUAGE, "en"]
- default_language_only: !ENV [DEFAULT_LANGUAGE_ONLY, false]
languages:
- default:
- name: Default (en)
- build: true
- en:
+ - locale: en
name: English
build: true
- site_name: "MkDocs static i18n plugin demo (en)"
- fr:
+ default: true
+ - locale: fr
name: Français
build: true
- site_name: "Démo du plugin MkDocs static i18n (fr)"
- nav_translations:
- fr:
- Topic1: Sujet1
- Topic2: Sujet2
+
- git-revision-date-localized
\ No newline at end of file
diff --git a/tests/fixtures/i18n/mkdocs_wrong_order.yml b/tests/fixtures/i18n/mkdocs_wrong_order.yml
index c2f7ccd..ba24236 100644
--- a/tests/fixtures/i18n/mkdocs_wrong_order.yml
+++ b/tests/fixtures/i18n/mkdocs_wrong_order.yml
@@ -27,21 +27,13 @@ plugins:
- search
- git-revision-date-localized
- i18n:
- default_language: !ENV [DEFAULT_LANGUAGE, "en"]
- default_language_only: !ENV [DEFAULT_LANGUAGE_ONLY, false]
languages:
- default:
- name: Default (en)
- build: true
- en:
+ - locale: en
name: English
build: true
- site_name: "MkDocs static i18n plugin demo (en)"
- fr:
+ default: true
+ - locale: fr
name: Français
build: true
- site_name: "Démo du plugin MkDocs static i18n (fr)"
- nav_translations:
- fr:
- Topic1: Sujet1
- Topic2: Sujet2
+
+
diff --git a/tests/test_builds.py b/tests/test_builds.py
index 5af31c6..de1387f 100644
--- a/tests/test_builds.py
+++ b/tests/test_builds.py
@@ -30,6 +30,7 @@
# package module
from mkdocs_git_revision_date_localized_plugin.util import Util
from mkdocs_git_revision_date_localized_plugin.ci import commit_count
+from mkdocs_git_revision_date_localized_plugin.dates import get_date_formats
# ##################################
# ######## Globals #################
@@ -147,6 +148,7 @@ def setup_commit_history(testproject_path):
testproject_path = str(testproject_path)
repo = git.Repo.init(testproject_path, bare=False)
+ repo.git.checkout("-b", "master")
author = "Test Person "
@@ -342,18 +344,6 @@ def validate_mkdocs_file(temp_path: str, mkdocs_yml_file: str):
# ##################################
-def test_date_formats():
- u = Util()
- assert u._date_formats(1582397529) == {
- "date": "February 22, 2020",
- "datetime": "February 22, 2020 18:52:09",
- "iso_date": "2020-02-22",
- "iso_datetime": "2020-02-22 18:52:09",
- "timeago": '',
- "custom": '22. February 2020',
- }
-
-
@pytest.mark.parametrize("mkdocs_file", MKDOCS_FILES, ids=lambda x: f"mkdocs file: {x}")
def test_tags_are_replaced(tmp_path, mkdocs_file):
"""
@@ -390,7 +380,7 @@ def test_tags_are_replaced(tmp_path, mkdocs_file):
# the revision date was in 'setup_commit_history' was set to 1642911026 (Sun Jan 23 2022 04:10:26 GMT+0000)
# Assert {{ git_revision_date_localized }} is replaced
- date_formats_revision_date = Util()._date_formats(1642911026,
+ date_formats_revision_date = get_date_formats(1642911026,
locale=plugin_config.get("locale"),
time_zone=plugin_config.get("timezone"),
custom_format=plugin_config.get("custom_format")
@@ -403,7 +393,7 @@ def test_tags_are_replaced(tmp_path, mkdocs_file):
# The last site revision was set in setup_commit_history to 1643911026 (Thu Feb 03 2022 17:57:06 GMT+0000)
# Assert {{ git_site_revision_date_localized }} is replaced
- date_formats_revision_date = Util()._date_formats(1643911026,
+ date_formats_revision_date = get_date_formats(1643911026,
locale=plugin_config.get("locale"),
time_zone=plugin_config.get("timezone"),
custom_format=plugin_config.get("custom_format")
@@ -416,7 +406,7 @@ def test_tags_are_replaced(tmp_path, mkdocs_file):
# Note {{ git_creation_date_localized }} is only replaced when configured in the config
if plugin_config.get("enable_creation_date"):
# The creation of page_with_tag.md was set in setup_commit_history to 1500854705 ( Mon Jul 24 2017 00:05:05 GMT+0000 )
- date_formats_revision_date = Util()._date_formats(1500854705,
+ date_formats_revision_date = get_date_formats(1500854705,
locale=plugin_config.get("locale"),
time_zone=plugin_config.get("timezone"),
custom_format=plugin_config.get("custom_format")
@@ -628,6 +618,10 @@ def test_low_fetch_depth(tmp_path, caplog):
# Clone the local repo with fetch depth of 1
repo = git.Repo.init(cloned_folder, bare=False)
+ try:
+ repo.heads.main.rename("master", force=True)
+ except:
+ pass
origin = repo.create_remote("origin", str(testproject_path))
origin.fetch(depth=1, prune=True)
repo.create_head(
diff --git a/tests/test_dates.py b/tests/test_dates.py
new file mode 100644
index 0000000..bbe0e94
--- /dev/null
+++ b/tests/test_dates.py
@@ -0,0 +1,72 @@
+import pytest
+from datetime import datetime, timezone
+from babel.dates import get_timezone
+
+from mkdocs_git_revision_date_localized_plugin.dates import get_date_formats
+
+
+
+def test_get_dates():
+ # Test with default arguments
+ expected_output = {
+ "date": "January 1, 1970",
+ "datetime": "January 1, 1970 00:00:00",
+ "iso_date": "1970-01-01",
+ "iso_datetime": "1970-01-01 00:00:00",
+ "timeago": '',
+ "custom": "01. January 1970"
+ }
+ assert get_date_formats(0) == expected_output
+
+ # Test with custom arguments
+ expected_output = {
+ "date": "January 1, 1970",
+ "datetime": "January 1, 1970 00:00:00",
+ "iso_date": "1970-01-01",
+ "iso_datetime": "1970-01-01 00:00:00",
+ "timeago": '',
+ "custom": "01. Jan 1970"
+ }
+ assert get_date_formats(0, locale="en", time_zone="UTC", custom_format="%d. %b %Y") == expected_output
+
+ # Test with non-UTC timezone
+ expected_output = {
+ "date": "January 1, 1970",
+ "datetime": "January 1, 1970 02:00:00",
+ "iso_date": "1970-01-01",
+ "iso_datetime": "1970-01-01 02:00:00",
+ "timeago": '',
+ "custom": "01. January 1970"
+ }
+ loc_dt = datetime(1970, 1, 1, 1, 0, 0, tzinfo=get_timezone("Europe/Berlin"))
+ unix_timestamp = loc_dt.replace(tzinfo=timezone.utc).timestamp()
+ assert get_date_formats(unix_timestamp, time_zone="Europe/Berlin") == expected_output
+
+ # Test with missing arguments
+ with pytest.raises(TypeError):
+ get_date_formats() # noqa
+
+ # Test with invalid timezone
+ with pytest.raises(LookupError):
+ get_date_formats(0, time_zone="Invalid/Timezone")
+
+ # Test with more recent date
+ expected_output = {
+ 'date': 'October 15, 2023',
+ 'datetime': 'October 15, 2023 13:32:04',
+ 'iso_date': '2023-10-15',
+ 'iso_datetime': '2023-10-15 13:32:04',
+ 'timeago': '',
+ 'custom': '15. October 2023'
+ }
+ assert get_date_formats(1697369524, time_zone="Europe/Amsterdam") == expected_output
+
+
+ assert get_date_formats(1582397529) == {
+ "date": "February 22, 2020",
+ "datetime": "February 22, 2020 18:52:09",
+ "iso_date": "2020-02-22",
+ "iso_datetime": "2020-02-22 18:52:09",
+ "timeago": '',
+ "custom": '22. February 2020',
+ }
\ No newline at end of file
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
deleted file mode 100644
index 3d60de8..0000000
--- a/tests/test_plugin.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#! python3 # noqa E265
-
-"""
- Test for the plugin class (subclass of mkdocs.BasePlugin).
-
- Usage from the repo root folder:
-
- # all tests
- python -m unittest tests.test_plugin
-
- # specific test
- python -m unittest tests.test_plugin.TestMkdocsPlugin.
-"""
-
-# #############################################################################
-# ########## Libraries #############
-# ##################################
-
-# Standard library
-from pathlib import Path
-import logging
-import unittest
-
-# MkDocs
-from mkdocs.config import load_config
-
-# package
-from mkdocs_git_revision_date_localized_plugin.plugin import (
- GitRevisionDateLocalizedPlugin,
-)
-
-
-# #############################################################################
-# ######## Globals #################
-# ##################################
-
-# make this test module easily reusable
-PLUGIN_NAME = "git-revision-date-localized"
-
-# custom log level to get plugin info messages
-logging.basicConfig(level=logging.INFO)
-
-# #############################################################################
-# ########## Helpers ###############
-# ##################################
-
-
-# #############################################################################
-# ########## Classes ###############
-# ##################################
-
-
-class TestMkdocsPlugin(unittest.TestCase):
- """MkDocs plugin module."""
-
- # -- Standard methods --------------------------------------------------------
- @classmethod
- def setUpClass(cls):
- """Executed when module is loaded before any test."""
- cls.fixtures_mkdocs_config_files = sorted(
- Path("tests/basic_setup").glob("*.yml")
- )
-
- cls.fixtures_config_cases_ok = {
- "default_explicit": {
- "type": "date",
- "locale": "en",
- "fallback_to_build_date": False,
- },
- # locale variations
- "default_no_locale": {"type": "date", "fallback_to_build_date": False},
- "custom_locale": {"locale": "fr"},
- # type variations
- "type_datetime": {"type": "datetime"},
- "type_iso_date": {"type": "iso_date"},
- "type_iso_datetime": {"type": "iso_datetime"},
- "type_timeago": {"type": "timeago"},
- # falbback variations
- "fallback_true": {"fallback_to_build_date": True},
- }
-
- cls.fixtures_config_cases_bad = {
- "invalid_option_name": {"language": "en",},
- # "invalid_value": {"type": "calendar", "locale": "nl"},
- "invalid_value_type": {"type": 1, "locale": "de"},
- }
-
- def setUp(self):
- """Executed before each test."""
- pass
-
- def tearDown(self):
- """Executed after each test."""
- pass
-
- @classmethod
- def tearDownClass(cls):
- """Executed after the last test."""
- pass
-
- # -- TESTS ---------------------------------------------------------
-
- # -- GET --
- def test_plugin_instanciation(self):
- """Simple test plugin instanciation"""
- # instanciate
- plg = GitRevisionDateLocalizedPlugin()
-
- # default values
- self.assertIsInstance(plg.config, dict)
- self.assertEqual(plg.config, {})
-
- def test_plugin_load_configs_ok(self):
- """Test inherited plugin load_config method on good configurations"""
- # instanciate
- plg = GitRevisionDateLocalizedPlugin()
-
- # parse fixtures configurations alone
- for i in self.fixtures_config_cases_ok:
- cfg = self.fixtures_config_cases_ok.get(i)
- out_cfg = plg.load_config(options=cfg)
-
- # check if config loader returned no errors
- self.assertIsInstance(out_cfg, tuple)
- [self.assertListEqual(v, []) for v in out_cfg]
- self.assertEqual(all([len(i) == 0 for i in out_cfg]), True)
-
- # try associating mkdocs configuration
- for i in self.fixtures_mkdocs_config_files:
- out_cfg_mkdocs = plg.load_config(
- options=cfg, config_file_path=str(i.resolve())
- )
-
- # check if config loader returned no errors
- self.assertIsInstance(out_cfg_mkdocs, tuple)
- [self.assertListEqual(v, []) for v in out_cfg_mkdocs]
- self.assertEqual(all([len(i) == 0 for i in out_cfg_mkdocs]), True)
-
- def test_plugin_load_configs_bad(self):
- """Test inherited plugin load_config method on bad configurations"""
- # instanciate
- plg = GitRevisionDateLocalizedPlugin()
-
- # simulate a complete configuration
- for i in self.fixtures_config_cases_bad:
- cfg = self.fixtures_config_cases_bad.get(i)
- out_cfg = plg.load_config(options=cfg)
-
- # check if config loader returned no errors
- self.assertIsInstance(out_cfg, tuple)
- self.assertEqual(all([len(i) == 0 for i in out_cfg]), False)
-
- # try associating mkdocs configuration
- for i in self.fixtures_mkdocs_config_files:
- out_cfg_mkdocs = plg.load_config(
- options=cfg, config_file_path=str(i.resolve())
- )
-
- # check if config loader returned no errors
- self.assertIsInstance(out_cfg_mkdocs, tuple)
- self.assertEqual(all([len(i) == 0 for i in out_cfg_mkdocs]), False)
-
- def test_plugin_on_config(self):
- """Test inherited plugin on_config method"""
- # load try associating mkdocs configuration
- for i in self.fixtures_mkdocs_config_files:
- # logging.info("Using Mkdocs configuration: %s " % i.resolve())
- cfg_mkdocs = load_config(str(i))
-
- # get mkdocs locale config - expected as future feature
- mkdocs_locale = cfg_mkdocs.get("locale", None)
-
- # get our plugin config and copy it
- plugin_loaded_from_mkdocs = cfg_mkdocs.get("plugins").get(PLUGIN_NAME)
- cfg_before_on_config = plugin_loaded_from_mkdocs.config.copy()
-
- # get theme configuration
- theme = cfg_mkdocs.get("theme") # -> Theme
-
- # look for the theme locale/language
- if "locale" in theme._vars:
- theme_locale = theme._vars.get("locale")
- elif "language" in theme._vars:
- theme_locale = theme._vars.get("language")
- else:
- theme_locale = None
-
- # execute on_config with global mkdocs loaded configuration and save config
- plugin_loaded_from_mkdocs.on_config(cfg_mkdocs)
- cfg_after_on_config = plugin_loaded_from_mkdocs.config.copy()
-
- # -- CASES for LOCALE ---------------------------------------
- result_locale = cfg_after_on_config.get("locale")
- # if locale set in plugin configuration = it the one!
- if cfg_before_on_config.get("locale"):
- self.assertEqual(result_locale, cfg_before_on_config.get("locale"))
- # if locale set in theme: it should be used
- elif theme_locale and not cfg_before_on_config.get("locale"):
- self.assertEqual(result_locale, theme_locale)
- # if locale not set in plugin nor in theme but in mkdocs = mkdocs
- elif (
- mkdocs_locale
- and not cfg_before_on_config.get("locale")
- and not theme_locale
- ):
- self.assertEqual(result_locale, mkdocs_locale)
- # if locale is not set at all = default = "en"
- else:
- self.assertEqual(result_locale, "en")
-
-
-# ##############################################################################
-# ##### Stand alone program ########
-# ##################################
-if __name__ == "__main__":
- unittest.main()