ics-query 0.3.1b0__tar.gz → 0.3.3b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/.github/workflows/tests.yml +35 -17
  2. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/PKG-INFO +34 -3
  3. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/README.md +31 -1
  4. ics_query-0.3.3b0/conftest.py +15 -0
  5. ics_query-0.3.3b0/ics-query.cmd +3 -0
  6. ics_query-0.3.3b0/ics-query.py +5 -0
  7. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/_version.py +2 -2
  8. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/cli.py +6 -4
  9. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/query.py +8 -1
  10. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/conftest.py +37 -16
  11. ics_query-0.3.3b0/ics_query/tests/runs/calendars/one-event-without-timezone.ics +14 -0
  12. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/test_command_line.py +19 -0
  13. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/pyproject.toml +1 -0
  14. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/tox.ini +27 -0
  15. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/.github/FUNDING.yml +0 -0
  16. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  17. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/.github/dependabot.yml +0 -0
  18. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/.gitignore +0 -0
  19. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/LICENSE +0 -0
  20. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics-query +0 -0
  21. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/__init__.py +0 -0
  22. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/__main__.py +0 -0
  23. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/parse.py +0 -0
  24. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/__init__.py +0 -0
  25. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/all --tz Singapore one-event.ics -.run +0 -0
  26. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/all three-events.ics -.run +0 -0
  27. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/at 2019-03-04 multiple-calendars.ics -.run +0 -0
  28. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/at 2019-03-04 one-event-twice.ics -.run +0 -0
  29. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/at 2019-03-04 one-event.ics -.run +0 -0
  30. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/at 2019-03-07 multiple-calendars.ics -.run +0 -0
  31. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/at 2024-08-20 Berlin-Los-Angeles.ics -.run +0 -0
  32. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/between 20240823 4d recurring-work-events.ics -.run +0 -0
  33. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/Berlin-Los-Angeles.ics +0 -0
  34. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/empty-calendar.ics +0 -0
  35. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/empty-file.ics +0 -0
  36. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/multiple-calendars.ics +0 -0
  37. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/one-event-twice.ics +0 -0
  38. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/one-event.ics +0 -0
  39. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/recurring-work-events.ics +0 -0
  40. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/simple-journal.ics +0 -0
  41. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/simple-todo.ics +0 -0
  42. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/calendars/three-events.ics +0 -0
  43. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first -c VJOURNAL -c VEVENT one-event.ics -.run +0 -0
  44. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first -c VJOURNAL one-event.ics -.run +0 -0
  45. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first -c VJOURNAL simple-journal.ics -.run +0 -0
  46. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first -c VTODO -c VJOURNAL simple-todo.ics -.run +0 -0
  47. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first -c VTODO simple-todo.ics -.run +0 -0
  48. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first empty-calendar.ics -.run +0 -0
  49. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first empty-file.ics -.run +0 -0
  50. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/runs/first recurring-work-events.ics -.run +0 -0
  51. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/test_parse_date.py +0 -0
  52. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/tests/test_parse_timedelta.py +0 -0
  53. {ics_query-0.3.1b0 → ics_query-0.3.3b0}/ics_query/version.py +0 -0
@@ -14,14 +14,15 @@ jobs:
14
14
  strategy:
15
15
  matrix:
16
16
  config:
17
- # [Python version, tox env]
18
- - ["3.9", "py39"]
19
- - ["3.10", "py310"]
20
- - ["3.11", "py311"]
21
- - ["3.12", "py312"]
22
- - ["3.9", "ruff"]
17
+ # [Python version, tox env, OS]
18
+ - ["3.9", "py39", "ubuntu-latest"]
19
+ - ["3.10", "py310", "ubuntu-latest"]
20
+ - ["3.11", "py311", "ubuntu-latest"]
21
+ - ["3.12", "py312", "ubuntu-latest"]
22
+ - ["3.9", "ruff", "ubuntu-latest"]
23
+ - ["3.11", "exe", "windows-latest"]
23
24
 
24
- runs-on: ubuntu-latest
25
+ runs-on: ${{ matrix.config[2] }}
25
26
  name: ${{ matrix.config[1] }}
26
27
  steps:
27
28
  - uses: actions/checkout@v4
@@ -29,14 +30,6 @@ jobs:
29
30
  uses: actions/setup-python@v5
30
31
  with:
31
32
  python-version: ${{ matrix.config[0] }}
32
- - name: Pip cache
33
- uses: actions/cache@v4
34
- with:
35
- path: ~/.cache/pip
36
- key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('pyproject.toml', 'tox.ini') }}
37
- restore-keys: |
38
- ${{ runner.os }}-pip-${{ matrix.config[0] }}-
39
- ${{ runner.os }}-pip-
40
33
  - name: Install dependencies
41
34
  run: |
42
35
  python -m pip install --upgrade pip
@@ -44,7 +37,14 @@ jobs:
44
37
  - name: Test
45
38
  run: |
46
39
  tox -e ${{ matrix.config[1] }}
47
-
40
+ - uses: actions/upload-artifact@v4
41
+ with:
42
+ name: dist-${{ matrix.config[1] }}-${{ matrix.config[2] }} # dist-exe-windows-latest
43
+ path: dist
44
+ if-no-files-found: ignore
45
+ retention-days: 1
46
+ compression-level: 0
47
+
48
48
  deploy-tag-to-pypi:
49
49
  name: Publish Package on PyPI
50
50
  # only deploy on tags, see https://stackoverflow.com/a/58478262/1320237
@@ -95,6 +95,18 @@ jobs:
95
95
  twine check dist/*
96
96
  twine upload dist/*
97
97
 
98
+ # artifact-check:
99
+ # name: artifact check
100
+ # runs-on: ubuntu-latest
101
+ # needs:
102
+ # - run-tests
103
+ # steps:
104
+ # - uses: actions/download-artifact@v4
105
+ # with:
106
+ # pattern: dist-*
107
+ # path: dist
108
+ # - run: ls -R dist
109
+
98
110
  github-release:
99
111
  name: "Publish GitHub Release"
100
112
  # only deploy on tags, see https://stackoverflow.com/a/58478262/1320237
@@ -105,9 +117,15 @@ jobs:
105
117
  runs-on: ubuntu-latest
106
118
  steps:
107
119
  - uses: actions/checkout@v4
120
+ - uses: actions/download-artifact@v4
121
+ with:
122
+ pattern: dist-*
123
+ path: dist
124
+ - run: ls -R dist
108
125
  - name: create release
109
126
  uses: ncipollo/release-action@v1
110
127
  with:
111
128
  allowUpdates: true
112
129
  body: "For a list of changes, please refer to the [Changelog](https://github.com/niccokunzmann/ics-query#changelog)."
113
- generateReleaseNotes: false
130
+ generateReleaseNotes: false
131
+ artifacts: "dist/dist-exe-windows-latest/ics-query.exe"
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ics-query
3
- Version: 0.3.1b0
3
+ Version: 0.3.3b0
4
4
  Summary: Find out what happens in ICS calendar files - query and filter RFC 5545 compatible .ics files for events, journals, TODOs and more.
5
5
  Project-URL: Homepage, https://github.com/niccokunzmann/ics-query/
6
6
  Project-URL: Repository, https://github.com/niccokunzmann/ics-query/
7
- Project-URL: source_archive, https://github.com/niccokunzmann/ics-query/archive/985400ff5c4df0ea4ad62422ef5c5c5e98face07.zip
7
+ Project-URL: source_archive, https://github.com/niccokunzmann/ics-query/archive/b25d84b7ea3a72f12c992e3702f8e082159fc71f.zip
8
8
  Project-URL: Issues, https://github.com/niccokunzmann/ics-query/issues
9
9
  Project-URL: Documentation, https://github.com/niccokunzmann/ics-query/
10
10
  Project-URL: Changelog, https://github.com/niccokunzmann/ics-query/#changelog
@@ -699,6 +699,7 @@ Requires-Python: >=3.9
699
699
  Requires-Dist: click
700
700
  Requires-Dist: icalendar
701
701
  Requires-Dist: recurring-ical-events<4,>=3.2.0
702
+ Requires-Dist: tzlocal
702
703
  Requires-Dist: x-wr-timezone
703
704
  Provides-Extra: test
704
705
  Requires-Dist: pytest; extra == 'test'
@@ -723,6 +724,8 @@ You can install this package from the [PyPI].
723
724
  pip install ics-query
724
725
  ```
725
726
 
727
+ For **Windows**, you can download `ics-query.exe` from our [Releases].
728
+
726
729
  ## Support
727
730
 
728
731
  - Support using [GitHub Sponsors]
@@ -733,7 +736,20 @@ pip install ics-query
733
736
  We accept donations to sustain our work, once or regular.
734
737
  Consider donating money to open-source as everyone benefits.
735
738
 
739
+ ## Supported Features
740
+
741
+ This library is based on
742
+
743
+ - [recurring-ical-events]
744
+ - [icalendar]
745
+ - [x-wr-timezone]
736
746
 
747
+ [recurring-ical-events]: https://pypi.org/project/recurring-ical-events/
748
+ [icalendar]: https://pypi.org/project/icalendar/
749
+ [x-wr-timezone]: https://pypi.org/project/x-wr-timezone/
750
+
751
+ For a list of supported features and RFC compatibility,
752
+ please refer to their documentation, too.
737
753
 
738
754
  ## Usage
739
755
 
@@ -741,6 +757,10 @@ Consider donating money to open-source as everyone benefits.
741
757
  accessible and easy.
742
758
  This section walks you though the different functionalities.
743
759
 
760
+ ```shell
761
+ ics-query --help
762
+ ```
763
+
744
764
  ### Examples
745
765
 
746
766
  You can get a calendar from the web and see what is on.
@@ -922,7 +942,7 @@ You can specify which components you would like to get using the
922
942
  -c VEVENT # only events
923
943
  -c VTODO # only TODOs
924
944
  -c VJOURNAL # only journal entries
925
- -c VEVENT -v VTODO # only events and journal entries
945
+ -c VEVENT -c VTODO # only events and journal entries
926
946
  ```
927
947
 
928
948
  This example returns the first event of a calendar.
@@ -1071,6 +1091,16 @@ To release new versions,
1071
1091
 
1072
1092
  ## Changelog
1073
1093
 
1094
+ - v0.3.3b
1095
+
1096
+ - Update dependencies
1097
+
1098
+ - v0.3.2b
1099
+
1100
+ - Fix that `--tz localtime` would use `localtime` as timezone name instead of the local timezone name.
1101
+ - Fix tests on Windows
1102
+ - Add Windows .exe build artifact
1103
+
1074
1104
  - v0.3.1b
1075
1105
 
1076
1106
  - Add `--license` option
@@ -1148,3 +1178,4 @@ Examples:
1148
1178
  [Polar]: https://polar.sh/niccokunzmann/ics-query
1149
1179
  [GitHub Sponsors]: https://github.com/sponsors/niccokunzmann
1150
1180
  [thanks.dev]: https://thanks.dev
1181
+ [Releases]: https://github.com/niccokunzmann/ics-query/releases
@@ -17,6 +17,8 @@ You can install this package from the [PyPI].
17
17
  pip install ics-query
18
18
  ```
19
19
 
20
+ For **Windows**, you can download `ics-query.exe` from our [Releases].
21
+
20
22
  ## Support
21
23
 
22
24
  - Support using [GitHub Sponsors]
@@ -27,7 +29,20 @@ pip install ics-query
27
29
  We accept donations to sustain our work, once or regular.
28
30
  Consider donating money to open-source as everyone benefits.
29
31
 
32
+ ## Supported Features
33
+
34
+ This library is based on
35
+
36
+ - [recurring-ical-events]
37
+ - [icalendar]
38
+ - [x-wr-timezone]
30
39
 
40
+ [recurring-ical-events]: https://pypi.org/project/recurring-ical-events/
41
+ [icalendar]: https://pypi.org/project/icalendar/
42
+ [x-wr-timezone]: https://pypi.org/project/x-wr-timezone/
43
+
44
+ For a list of supported features and RFC compatibility,
45
+ please refer to their documentation, too.
31
46
 
32
47
  ## Usage
33
48
 
@@ -35,6 +50,10 @@ Consider donating money to open-source as everyone benefits.
35
50
  accessible and easy.
36
51
  This section walks you though the different functionalities.
37
52
 
53
+ ```shell
54
+ ics-query --help
55
+ ```
56
+
38
57
  ### Examples
39
58
 
40
59
  You can get a calendar from the web and see what is on.
@@ -216,7 +235,7 @@ You can specify which components you would like to get using the
216
235
  -c VEVENT # only events
217
236
  -c VTODO # only TODOs
218
237
  -c VJOURNAL # only journal entries
219
- -c VEVENT -v VTODO # only events and journal entries
238
+ -c VEVENT -c VTODO # only events and journal entries
220
239
  ```
221
240
 
222
241
  This example returns the first event of a calendar.
@@ -365,6 +384,16 @@ To release new versions,
365
384
 
366
385
  ## Changelog
367
386
 
387
+ - v0.3.3b
388
+
389
+ - Update dependencies
390
+
391
+ - v0.3.2b
392
+
393
+ - Fix that `--tz localtime` would use `localtime` as timezone name instead of the local timezone name.
394
+ - Fix tests on Windows
395
+ - Add Windows .exe build artifact
396
+
368
397
  - v0.3.1b
369
398
 
370
399
  - Add `--license` option
@@ -442,3 +471,4 @@ Examples:
442
471
  [Polar]: https://polar.sh/niccokunzmann/ics-query
443
472
  [GitHub Sponsors]: https://github.com/sponsors/niccokunzmann
444
473
  [thanks.dev]: https://thanks.dev
474
+ [Releases]: https://github.com/niccokunzmann/ics-query/releases
@@ -0,0 +1,15 @@
1
+ """Add options so they can be found by pytest.
2
+
3
+ See https://stackoverflow.com/a/31526934/1320237
4
+ """
5
+
6
+ import pytest
7
+
8
+
9
+ def pytest_addoption(parser: pytest.Parser):
10
+ """Add options to pytest."""
11
+ # see https://stackoverflow.com/a/58425144
12
+ parser.addoption(
13
+ "--binary", action="store", default="ics-query", help="the ics-query command"
14
+ )
15
+ print("addoption")
@@ -0,0 +1,3 @@
1
+ @ echo off
2
+
3
+ .\.venv\Scripts\ics-query.exe %*
@@ -0,0 +1,5 @@
1
+ """ics-query script for pyinstaller."""
2
+
3
+ from ics_query import main
4
+
5
+ main()
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.3.1b0'
16
- __version_tuple__ = version_tuple = (0, 3, 1)
15
+ __version__ = version = '0.3.3b0'
16
+ __version_tuple__ = version_tuple = (0, 3, 3)
@@ -25,6 +25,7 @@ import zoneinfo
25
25
 
26
26
  import click
27
27
  from icalendar.cal import Calendar, Component
28
+ from tzlocal import get_localzone_name
28
29
 
29
30
  from . import parse
30
31
  from .query import Query
@@ -181,17 +182,18 @@ def opt_available_timezones(*param_decls: str, **kwargs: t.Any) -> t.Callable:
181
182
  """List available timezones.
182
183
 
183
184
  This is copied from the --help option.
185
+
186
+ Commonly used timezone names are added first.
184
187
  """
185
188
 
186
189
  def callback(ctx: click.Context, param: click.Parameter, value: bool) -> None: # noqa: FBT001, ARG001
187
190
  if not value or ctx.resilient_parsing:
188
191
  return
189
192
 
190
- first_zones = ["localtime", "UTC"]
193
+ click.echo("localtime") # special local time handle
194
+ click.echo(get_localzone_name())
195
+ click.echo("UTC")
191
196
  all_zones = zoneinfo.available_timezones()
192
- for zone in first_zones:
193
- if zone in all_zones:
194
- click.echo(zone)
195
197
  for zone in sorted(all_zones, key=str.lower):
196
198
  click.echo(zone)
197
199
  ctx.exit()
@@ -23,6 +23,7 @@ from typing import TYPE_CHECKING
23
23
 
24
24
  import x_wr_timezone
25
25
  from recurring_ical_events import CalendarQuery, Occurrence
26
+ from tzlocal import get_localzone
26
27
 
27
28
  if TYPE_CHECKING:
28
29
  from collections.abc import Sequence
@@ -38,7 +39,13 @@ class Query(CalendarQuery):
38
39
  components=components,
39
40
  skip_bad_series=True,
40
41
  )
41
- self.timezone = zoneinfo.ZoneInfo(timezone) if timezone else None
42
+ self.timezone = self.get_timezone(timezone)
43
+
44
+ def get_timezone(self, timezone: str) -> datetime.tzinfo | None:
45
+ """Return the local time tz."""
46
+ if timezone == "localtime":
47
+ return get_localzone()
48
+ return zoneinfo.ZoneInfo(timezone) if timezone else None
42
49
 
43
50
  def with_timezone(self, dt: datetime.date | datetime.datetime):
44
51
  """Add the timezone."""
@@ -18,7 +18,6 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  import subprocess
21
- from copy import deepcopy
22
21
  from pathlib import Path
23
22
  from typing import Callable, NamedTuple
24
23
 
@@ -50,14 +49,28 @@ class TestRun(NamedTuple):
50
49
  )
51
50
 
52
51
 
53
- def run_ics_query(*command, cwd=CALENDARS_DIRECTORY) -> TestRun:
54
- """Run ics-qeury with a command."""
55
- cmd = ["ics-query", *command]
56
- print(" ".join(cmd))
52
+ def get_binary_path(request: pytest.FixtureRequest) -> str:
53
+ """Return the path to the ics-query command."""
54
+ command: str = request.config.getoption("--binary")
55
+ if command == "ics-query":
56
+ # The default command can be found on the command line
57
+ return command
58
+ # we must set the path to be absolute
59
+ return Path(command).absolute()
60
+
61
+
62
+ def run_ics_query(*command, cwd=CALENDARS_DIRECTORY, binary: str) -> TestRun:
63
+ """Run ics-qeury with a command.
64
+
65
+ - cwd is the working directory
66
+ - binary is the path to the command
67
+ """
68
+ cmd = [binary, *command]
69
+ print(" ".join(map(str, cmd)))
57
70
  completed_process = subprocess.run( # noqa: S603, RUF100
58
71
  cmd, # noqa: S603, RUF100
59
72
  capture_output=True,
60
- timeout=3,
73
+ timeout=10,
61
74
  check=False,
62
75
  cwd=cwd,
63
76
  )
@@ -71,35 +84,43 @@ class IOTestCase(NamedTuple):
71
84
  command: list[str]
72
85
  location: Path
73
86
  expected_output: str
87
+ binary: str
74
88
 
75
89
  @classmethod
76
- def from_path(cls, path: Path) -> IOTestCase:
90
+ def from_path(cls, path: Path, binary: str) -> IOTestCase:
77
91
  """Create a new testcase from the files."""
78
92
  expected_output = path.read_text(encoding="UTF-8").replace("\r\n", "\n")
79
- return cls(path.name, path.stem.split(), path.parent, expected_output)
93
+ return cls(path.name, path.stem.split(), path.parent, expected_output, binary)
80
94
 
81
95
  def run(self) -> TestRun:
82
96
  """Run this test case and return the result."""
83
- return run_ics_query(*self.command)
97
+ return run_ics_query(*self.command, binary=self.binary)
84
98
 
85
99
 
86
- io_test_cases = [
87
- IOTestCase.from_path(test_case_path)
100
+ io_test_case_paths = [
101
+ test_case_path
88
102
  for test_case_path in IO_DIRECTORY.iterdir()
89
103
  if test_case_path.is_file()
90
104
  ]
91
105
 
92
106
 
93
- @pytest.fixture(params=io_test_cases)
94
- def io_testcase(request) -> IOTestCase:
107
+ @pytest.fixture(params=io_test_case_paths)
108
+ def io_testcase(request: pytest.FixtureRequest) -> IOTestCase:
95
109
  """Go though all the IO test cases."""
96
- return deepcopy(request.param)
110
+ path: Path = request.param
111
+ binary = get_binary_path(request)
112
+ return IOTestCase.from_path(path, binary)
97
113
 
98
114
 
99
115
  @pytest.fixture
100
- def run() -> Callable[..., TestRun]:
116
+ def run(request: pytest.FixtureRequest) -> Callable[..., TestRun]:
101
117
  """Return a runner function."""
102
- return run_ics_query
118
+
119
+ def run(*args, **kw):
120
+ kw["binary"] = get_binary_path(request)
121
+ return run_ics_query(*args, **kw)
122
+
123
+ return run
103
124
 
104
125
 
105
126
  __all__ = ["IOTestCase", "TestRun"]
@@ -0,0 +1,14 @@
1
+ BEGIN:VCALENDAR
2
+ VERSION:2.0
3
+ PRODID:-//SabreDAV//SabreDAV//EN
4
+ CALSCALE:GREGORIAN
5
+ BEGIN:VEVENT
6
+ CREATED:20190303T111937
7
+ DTSTAMP:20190303T111937
8
+ LAST-MODIFIED:20190303T111937
9
+ UID:UYDQSG9TH4DE0WM3QFL2J
10
+ SUMMARY:test1
11
+ DTSTART:20190304T080000
12
+ DTEND:20190304T083000
13
+ END:VEVENT
14
+ END:VCALENDAR
@@ -15,6 +15,8 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
  """Test the commmand line."""
17
17
 
18
+ from tzlocal import get_localzone_name
19
+
18
20
  from ics_query.version import version
19
21
 
20
22
  from .conftest import IOTestCase
@@ -51,3 +53,20 @@ def test_timezones(run):
51
53
  assert tz.index("Zulu") > tz.index("Pacific/Nauru")
52
54
  assert tz.index("Pacific/Nauru") > tz.index("UTC")
53
55
  assert tz.index("UTC") > tz.index("localtime")
56
+
57
+
58
+ def test_special_timezones(run):
59
+ """Make sure we show special timezones first."""
60
+ result = run("--available-timezones")
61
+ tz = result.output.split()
62
+ assert result.exit_code == 0
63
+ assert tz[0] == "localtime"
64
+ assert tz[1] == get_localzone_name()
65
+ assert tz[2] == "UTC"
66
+
67
+
68
+ def test_localtime_is_not_in_the_result_string(run):
69
+ """We do not want 'localtime' to turn up as the result tz name."""
70
+ result = run("first", "--tz", "localtime", "one-event-without-timezone.ics")
71
+ assert f"DTSTART;TZID={get_localzone_name()}:201903" in result.output
72
+ assert f"DTEND;TZID={get_localzone_name()}:201903" in result.output
@@ -49,6 +49,7 @@ dependencies = [
49
49
  "recurring-ical-events>=3.2.0,<4",
50
50
  "click",
51
51
  "x-wr-timezone",
52
+ "tzlocal",
52
53
  ]
53
54
 
54
55
  [project.optional-dependencies]
@@ -8,6 +8,9 @@ skipsdist = True
8
8
  envlist = py39, py310, py311, py312, ruff
9
9
 
10
10
  [testenv]
11
+ #
12
+ # Run the tests
13
+ #
11
14
  deps =
12
15
  -e {tox_root}[test]
13
16
  setenv = TMPDIR={envtmpdir}
@@ -15,8 +18,32 @@ commands =
15
18
  pytest --basetemp="{envtmpdir}" {posargs}
16
19
 
17
20
  [testenv:ruff]
21
+ #
22
+ # Format the code according to convention
23
+ #
18
24
  deps = ruff
19
25
  skip_install = True
20
26
  commands =
21
27
  ruff format
22
28
  ruff check --fix
29
+
30
+ [testenv:build]
31
+ #
32
+ # Build the distribution files
33
+ #
34
+ deps = build
35
+ skip_install = True
36
+ commands =
37
+ python -m build .
38
+
39
+ [testenv:exe]
40
+ #
41
+ # Create a Windows executable and run the tests with it
42
+ #
43
+ skip_install = True
44
+ deps =
45
+ pyinstaller
46
+ -e .[test]
47
+ commands =
48
+ pyinstaller ics-query.py --onefile --paths "{env_site_packages_dir}" --recursive-copy-metadata ics-query
49
+ pytest --binary .\dist\ics-query.exe
File without changes
File without changes
File without changes