mirror of
https://github.com/novoid/appendfilename.git
synced 2026-06-14 12:21:25 +00:00
commit
683be702bb
5 changed files with 180 additions and 191 deletions
7
.github/workflows/pytest.yml
vendored
7
.github/workflows/pytest.yml
vendored
|
|
@ -3,7 +3,7 @@ name: CI_pytest_appendfilename
|
||||||
# name : pytest.yml
|
# name : pytest.yml
|
||||||
# purpose : regularly run pytest on appendfilename
|
# purpose : regularly run pytest on appendfilename
|
||||||
# date : [2024-10-31 Thu]
|
# date : [2024-10-31 Thu]
|
||||||
# edit : [2024-11-12 Tue]
|
# edit : [2024-11-22 Fri]
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -43,7 +43,10 @@ jobs:
|
||||||
|
|
||||||
- name: run the check by pytest
|
- name: run the check by pytest
|
||||||
run: |
|
run: |
|
||||||
|
echo "default"
|
||||||
python -m pytest -m "default"
|
python -m pytest -m "default"
|
||||||
|
echo "prepend"
|
||||||
python -m pytest -m "prepend"
|
python -m pytest -m "prepend"
|
||||||
python -m pytest -m "smart"
|
echo "smart_prepend"
|
||||||
|
python -m pytest -m "smart_prepend"
|
||||||
|
|
||||||
|
|
|
||||||
21
Makefile
21
Makefile
|
|
@ -1,21 +0,0 @@
|
||||||
# GNU Make file for the automation of pytest for appendfilename
|
|
||||||
#
|
|
||||||
# While the test script is written for Python 3.9.2, it depends on
|
|
||||||
# your installation of pytest (and in case of Linux, the authors of
|
|
||||||
# your distribution) if pytest for Python 3 is invoked either by
|
|
||||||
# pytest, or pytest-3. In some distributions, pytest actually may
|
|
||||||
# invoke pyest for legacy Python 2; the tests in test_date2name.py
|
|
||||||
# however are incompatible to this.
|
|
||||||
#
|
|
||||||
# Put this file like test_appendfilename.py in the root folder of
|
|
||||||
# appendfilename fetched from PyPi or GitHub. Then run
|
|
||||||
#
|
|
||||||
# chmod +x *
|
|
||||||
# make ./Makefile
|
|
||||||
#
|
|
||||||
# to run the tests. If you want pytest to exit the test sequence
|
|
||||||
# right after the first test failing, use the -x flag to the
|
|
||||||
# instructions on the CLI in addition to the verbosity flag to (-v).
|
|
||||||
|
|
||||||
# pytest -v test_appendfilename.py # the pattern by pytest's manual
|
|
||||||
pytest-3 -v test_appendfilename.py # the alternative pattern (e.g., Debian 12)
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[pytest]
|
[pytest]
|
||||||
markers =
|
markers =
|
||||||
default: appendfilename's default string insertions
|
default: test appendfilename's default string insertion
|
||||||
prepend: appendfilename's optional -p/--prepend flag
|
prepend: test appendfilename's optional -p/--prepend flag
|
||||||
smart: appendfilename's optional --smart-prepend flag
|
smart_prepend: test appendfilename's optional --smart-prepend flag
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,23 @@
|
||||||
# author: nbehrnd@yahoo.com
|
# author: nbehrnd@yahoo.com
|
||||||
# license: GPL v3, 2022.
|
# license: GPL v3, 2022.
|
||||||
# date: 2022-01-05 (YYYY-MM-DD)
|
# date: 2022-01-05 (YYYY-MM-DD)
|
||||||
# edit: [2024-11-05 Tue]
|
# edit: [2024-11-22 Fri]
|
||||||
#
|
#
|
||||||
"""Test pad for functions by appendfilename with pytest.
|
"""Test pad for functions by appendfilename with pytest.
|
||||||
|
|
||||||
Initially written for Python 3.9.9 and pytest 6.2.4 and recently update
|
Initially written for Python 3.9.9 and pytest 6.2.4 and recently update
|
||||||
for Python 3.12.6/pytest 8.3.3, this script provides a programmatic check
|
for Python 3.12.6/pytest 8.3.3, this script provides a programmatic check
|
||||||
of functions offered by appendfilename. Deposit this script in the root of
|
of functions offered by appendfilename. Deposit this script in the root
|
||||||
the folder fetched and unzipped from PyPi or GitHub. Create a virtual
|
of the folder fetched and unzipped from PyPi or GitHub. Create a virtual
|
||||||
environment for Python, e.g. by
|
environment for Python, e.g. by
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
python -m venv sup
|
python -m venv sup
|
||||||
```
|
```
|
||||||
|
|
||||||
In the activated virtual environment, ensure the dependencies are met -
|
In the activated virtual environment, resolve the dependencies - either by
|
||||||
either by `pip install pyreadline3 pytest`, or `pip install -r requirements.txt`
|
`pip install pyreadline3 pytest`, or `pip install -r requirements.txt` -
|
||||||
- and launch the tests by
|
and launch the tests by
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
python -m pytest
|
python -m pytest
|
||||||
|
|
@ -29,26 +29,31 @@ python -m pytest
|
||||||
As a reminder, the following optional pytest flags may be useful to obtain
|
As a reminder, the following optional pytest flags may be useful to obtain
|
||||||
a report tailored to your needs:
|
a report tailored to your needs:
|
||||||
|
|
||||||
- `-x` exits right after the first failing test (reported by `E` instead of `.`)
|
- `-x` exit after the first failing test (reported by `E` instead of `.`)
|
||||||
- `-v` provide a more verbose output
|
- `-v` provide a more verbose output
|
||||||
- `-s` equally report the test criterion, e.g. the queried file name
|
- `-s` equally report the test criterion, e.g. the queried file name
|
||||||
|
|
||||||
|
Equally keep in mind you can constrain pytest tests. Labels assigned are
|
||||||
|
|
||||||
|
- default: test appendfilename's default string insertion
|
||||||
|
- prepend: test appendfilename's optional -p/--prepend flag
|
||||||
|
- smart_prepend: test appendfilename's optional --smart-prepend flag
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
PROGRAM = os.path.join("appendfilename", "__init__.py") # Cross-platform path
|
PROGRAM = os.path.join("appendfilename", "__init__.py")
|
||||||
|
|
||||||
# The following section tests the applications default pattern where a string
|
# The following section tests the applications default pattern where a
|
||||||
# is added to the file name, just prior to the file's file extension. The
|
# string is added to the file name, just prior to the file's file
|
||||||
# permutation of the three arguments and their levels defines 120 tests.
|
# extension. The permutations of the arguments define 120 tests.
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
||||||
|
|
@ -68,11 +73,14 @@ arg3_values = [
|
||||||
"--separator '='",
|
"--separator '='",
|
||||||
"--separator '-'"
|
"--separator '-'"
|
||||||
]
|
]
|
||||||
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
# Note: In Windows 10, the check with pytest and `*` as separator fails
|
||||||
|
# because it is not a permitted character in a file name there. See
|
||||||
|
# <https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file>
|
||||||
|
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.default
|
@pytest.mark.default
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
||||||
def test_append(arg1, arg2, arg3):
|
def test_append(arg1, arg2, arg3):
|
||||||
|
|
@ -89,7 +97,7 @@ def test_append(arg1, arg2, arg3):
|
||||||
# run the test to be tested:
|
# run the test to be tested:
|
||||||
full_command = ["python", PROGRAM, arg1
|
full_command = ["python", PROGRAM, arg1
|
||||||
] + shlex.split(arg2) + shlex.split(arg3)
|
] + shlex.split(arg2) + shlex.split(arg3)
|
||||||
subprocess.run(full_command, text = True, check = True)
|
subprocess.run(full_command, text=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be tested:
|
# construct the new file name to be tested:
|
||||||
if len(shlex.split(arg3)) == 0:
|
if len(shlex.split(arg3)) == 0:
|
||||||
|
|
@ -98,9 +106,8 @@ def test_append(arg1, arg2, arg3):
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
new_filename = "".join(
|
new_filename = "".join(
|
||||||
[ arg1[:-4], separator,
|
[arg1[:-4], separator, shlex.split(arg2)[1], ".txt"])
|
||||||
shlex.split(arg2)[1], ".txt" ])
|
print(f"test criterion: {new_filename}") # for an optional `pytest -s`
|
||||||
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
assert os.path.isfile(new_filename)
|
assert os.path.isfile(new_filename)
|
||||||
|
|
@ -109,9 +116,10 @@ def test_append(arg1, arg2, arg3):
|
||||||
os.remove(new_filename)
|
os.remove(new_filename)
|
||||||
assert os.path.isfile(new_filename) is False
|
assert os.path.isfile(new_filename) is False
|
||||||
|
|
||||||
# The following section is about tests to prepend a user defined string and
|
# The following section is about tests to prepend a user defined string
|
||||||
# an adjustable separator to the original file name of the file submitted. By
|
# and an adjustable separator to the original file name of the submitted
|
||||||
# permutation of the parameter's levels, this defines 240 tests.
|
# file. The permutation of the parameters defines 240 tests.
|
||||||
|
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
||||||
|
|
@ -140,6 +148,7 @@ arg4_values = [
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values, arg4_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values, arg4_values))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.prepend
|
@pytest.mark.prepend
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3, arg4", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3, arg4", test_cases)
|
||||||
def test_prepend(arg1, arg2, arg3, arg4):
|
def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
|
|
@ -158,7 +167,7 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
full_command = [
|
full_command = [
|
||||||
"python", PROGRAM, arg1
|
"python", PROGRAM, arg1
|
||||||
] + shlex.split(arg2) + shlex.split(arg3) + shlex.split(arg4)
|
] + shlex.split(arg2) + shlex.split(arg3) + shlex.split(arg4)
|
||||||
subprocess.run(full_command, text = True, check = True)
|
subprocess.run(full_command, text=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be tested:
|
# construct the new file name to be tested:
|
||||||
if len(shlex.split(arg3)) == 0:
|
if len(shlex.split(arg3)) == 0:
|
||||||
|
|
@ -166,7 +175,7 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
else:
|
else:
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
new_filename = "".join( [ shlex.split(arg2)[1], separator, arg1 ] )
|
new_filename = "".join([shlex.split(arg2)[1], separator, arg1])
|
||||||
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
|
|
@ -179,12 +188,13 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
# This section tests the insertion of a string into the file's file name
|
# This section tests the insertion of a string into the file's file name
|
||||||
# just after the file's time or date stamp as provided `date2name`.
|
# just after the file's time or date stamp as provided `date2name`.
|
||||||
|
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"2021-12-31T18.48.22_test.txt",
|
"2021-12-31T18.48.22_test.txt",
|
||||||
"2021-12-31_test.txt",
|
"2021-12-31_test.txt",
|
||||||
# "20211231_test.txt", # by now `20211231_test.txt` -> 20211231_test ping.txt
|
# "20211231_test.txt", # by now `20211231_test.txt` -> 20211231_test ping.txt
|
||||||
# "2021-12_test.txt", # by now `2021-12_test.txt` -> `2021-12_test ping.txt`
|
# "2021-12_test.txt", # by now `2021-12_test.txt` -> `2021-12_test ping.txt`
|
||||||
# "211231_test.txt" # by now `211231_test.txt` -> `211231_test ping.txt`
|
# "211231_test.txt" # by now `211231_test.txt` -> `211231_test ping.txt`
|
||||||
]
|
]
|
||||||
arg2_values = [
|
arg2_values = [
|
||||||
"-t book",
|
"-t book",
|
||||||
|
|
@ -194,15 +204,15 @@ arg2_values = [
|
||||||
]
|
]
|
||||||
arg3_values = [
|
arg3_values = [
|
||||||
"", # i.e. fall back to default single space
|
"", # i.e. fall back to default single space
|
||||||
# "--separator '!'",
|
# "--separator '!'",
|
||||||
# "--separator '@'",
|
# "--separator '@'",
|
||||||
# "--separator '#'",
|
# "--separator '#'",
|
||||||
# "--separator '$'",
|
# "--separator '$'",
|
||||||
# "--separator '%'",
|
# "--separator '%'",
|
||||||
# "--separator '_'",
|
# "--separator '_'",
|
||||||
# "--separator '+'",
|
# "--separator '+'",
|
||||||
# "--separator '='",
|
# "--separator '='",
|
||||||
# "--separator '-'"
|
# "--separator '-'"
|
||||||
]
|
]
|
||||||
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
||||||
# Contrasting to Linux Debian 13, a `pytest` in Windows 10 revealed every
|
# Contrasting to Linux Debian 13, a `pytest` in Windows 10 revealed every
|
||||||
|
|
@ -211,7 +221,8 @@ arg3_values = [
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
||||||
|
|
||||||
@pytest.mark.smart
|
|
||||||
|
@pytest.mark.smart_prepend
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
||||||
def test_smart_prepend(arg1, arg2, arg3):
|
def test_smart_prepend(arg1, arg2, arg3):
|
||||||
"""test the insertion of a new string just past the time stamp
|
"""test the insertion of a new string just past the time stamp
|
||||||
|
|
@ -220,18 +231,18 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
arg2 the text string to be added
|
arg2 the text string to be added
|
||||||
arg3 the separator (at least in Windows 10, do not use `*`
|
arg3 the separator (at least in Windows 10, do not use `*`
|
||||||
"""
|
"""
|
||||||
time_stamp = ""
|
timestamp = ""
|
||||||
time_stamp_separator = ""
|
# timestamp_separator = ""
|
||||||
old_filename_no_timestamp = ""
|
old_filename_no_timestamp = ""
|
||||||
|
|
||||||
# create a test file:
|
# create a test file:
|
||||||
with open(arg1, mode="w", encoding="utf-8") as newfile:
|
with open(arg1, mode="w", encoding="utf-8") as newfile:
|
||||||
newfile.write("this is a placeholder\n")
|
newfile.write("this is a placeholder\n")
|
||||||
|
|
||||||
#run `appendfilename` on this test file
|
# run `appendfilename` on this test file
|
||||||
run_appendfilename = " ".join(
|
run_appendfilename = " ".join(
|
||||||
["python", PROGRAM, arg1, arg2, arg3, " --smart-prepend"])
|
["python", PROGRAM, arg1, arg2, arg3, " --smart-prepend"])
|
||||||
subprocess.run(run_appendfilename, shell=True, check = True)
|
subprocess.run(run_appendfilename, shell=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be testedt:
|
# construct the new file name to be testedt:
|
||||||
old_filename = arg1
|
old_filename = arg1
|
||||||
|
|
@ -242,7 +253,7 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
else:
|
else:
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
# Time stamps `date2name` provides can be either one of five formats
|
# Timestamps `date2name` provides can be either one of five formats
|
||||||
#
|
#
|
||||||
# YYYY-MM-DDTHH.MM.SS `--withtime`
|
# YYYY-MM-DDTHH.MM.SS `--withtime`
|
||||||
# YYYY-MM-DD default
|
# YYYY-MM-DD default
|
||||||
|
|
@ -258,42 +269,39 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
# https://github.com/novoid/appendfilename/issues/15
|
# https://github.com/novoid/appendfilename/issues/15
|
||||||
# https://github.com/novoid/appendfilename/issues/16
|
# https://github.com/novoid/appendfilename/issues/16
|
||||||
|
|
||||||
# pattern `--with-time`
|
patterns = [
|
||||||
if re.search(r"^\d{4}-[012]\d-[0-3]\dT[012]\d\.[0-5]\d\.[0-5]\d", old_filename):
|
r"^\d{4}-[012]\d-[0-3]\dT[012]\d\.[0-5]\d\.[0-5]\d",
|
||||||
time_stamp = old_filename[:19]
|
r"^\d{4}-[012]\d-[0-3]\d",
|
||||||
time_stamp_separator = old_filename[19]
|
r"^\d{4}[012]\d[0-3]\d",
|
||||||
old_filename_no_timestamp = old_filename[20:]
|
r"^\d{4}-[012]\d",
|
||||||
|
r"^\d{2}[012]\d[0-3]\d"
|
||||||
|
]
|
||||||
|
|
||||||
# default pattern
|
for pattern in patterns:
|
||||||
elif re.search(r"^\d{4}-[012]\d-[0-3]\d", old_filename):
|
match = re.search(pattern, old_filename)
|
||||||
time_stamp = old_filename[:10]
|
if match:
|
||||||
time_stamp_separator = old_filename[10]
|
timestamp = re.findall(pattern, old_filename)[0]
|
||||||
old_filename_no_timestamp = old_filename[11:]
|
timestamp_separator = str(old_filename)[len(timestamp)]
|
||||||
|
old_filename_no_timestamp = old_filename[len(timestamp) + 1:]
|
||||||
|
|
||||||
# pattern `--compact` # currently fails
|
print("\n\ntest of option smart-prepend:") # `pytest -s` diagnosis
|
||||||
elif re.search(r"^\d{4}[012]\d[0-3]\d", old_filename):
|
print("old_filename:")
|
||||||
time_stamp = old_filename[:8]
|
print(old_filename)
|
||||||
time_stamp_separator = old_filename[8]
|
print("timestamp, timestamp_separator, old_filename_no_timestamp")
|
||||||
old_filename_no_timestamp = old_filename[9:]
|
print(timestamp)
|
||||||
|
print(timestamp_separator)
|
||||||
|
print(old_filename_no_timestamp)
|
||||||
|
|
||||||
# pattern `--month` # currently fails
|
break
|
||||||
elif re.search(r"^\d{4}-[012]\d", old_filename):
|
|
||||||
time_stamp = old_filename[:7]
|
|
||||||
time_stamp_separator = old_filename[7]
|
|
||||||
old_filename_no_timestamp = old_filename[8:]
|
|
||||||
|
|
||||||
# pattern `--short` # currently fails
|
new_filename = "".join([
|
||||||
elif re.search(r"^\d{4}[012]\d[0-3]\d", old_filename):
|
timestamp, # timestamp_separator,
|
||||||
time_stamp = old_filename[:6]
|
|
||||||
time_stamp_separator = old_filename[6]
|
|
||||||
old_filename_no_timestamp = old_filename[7:]
|
|
||||||
|
|
||||||
new_filename = "".join([time_stamp, #time_stamp_separator,
|
|
||||||
separator, shlex.split(arg2)[1], separator,
|
separator, shlex.split(arg2)[1], separator,
|
||||||
old_filename_no_timestamp ])
|
old_filename_no_timestamp
|
||||||
|
])
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
print("\nnew_filename") # optional check for `pytest -s`
|
print("new_filename") # optional check for `pytest -s`
|
||||||
print(new_filename)
|
print(new_filename)
|
||||||
assert os.path.isfile(new_filename)
|
assert os.path.isfile(new_filename)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# name: test_generator.org
|
# name: test_generator.org
|
||||||
# author: nbehrnd@yahoo.com
|
# author: nbehrnd@yahoo.com
|
||||||
# date: 2022-01-05 (YYYY-MM-DD)
|
# date: 2022-01-05 (YYYY-MM-DD)
|
||||||
# edit: [2024-11-05 Tue]
|
# edit: [2024-11-22 Fri]
|
||||||
# license: GPL3, 2022.
|
# license: GPL3, 2022-2024
|
||||||
# Export the tangled files with C-c C-v t
|
# Export the tangled files with C-c C-v t
|
||||||
|
|
||||||
#+PROPERTY: header-args :tangle yes
|
#+PROPERTY: header-args :tangle yes
|
||||||
|
|
@ -39,10 +39,10 @@ python -m pytest
|
||||||
- =-x= stops the sequence after the first failing test
|
- =-x= stops the sequence after the first failing test
|
||||||
- =-s= occasionally provides information e.g., about the tests' criteria
|
- =-s= occasionally provides information e.g., about the tests' criteria
|
||||||
|
|
||||||
The tests are organized in sets =default=, =prepend=, and =smart=.
|
The tests are organized in sets =default=, =prepend=, and =smart_prepend=.
|
||||||
This allows to selectively run only checks which are about the
|
This allows to selectively run only checks which are about the
|
||||||
results by =appendfilename= in the /default/ mode, /prepend/ mode,
|
results by =appendfilename= in the /default/ mode, /prepend/ mode,
|
||||||
or /smart prepend/ mode alone, e.g.
|
or /smart-prepend/ mode alone, e.g.
|
||||||
|
|
||||||
#+begin_src shell :tangle no
|
#+begin_src shell :tangle no
|
||||||
python -m pytest -m "prepend"
|
python -m pytest -m "prepend"
|
||||||
|
|
@ -104,17 +104,16 @@ python -m pytest -m "prepend"
|
||||||
: t
|
: t
|
||||||
|
|
||||||
If the previous block was evaluated as .TRUE. (=t=), test script and
|
If the previous block was evaluated as .TRUE. (=t=), test script and
|
||||||
Makefile may be tangled right now by =C-c C-v t=. After closing
|
=pytest.ini= may be tangled right now by =C-c C-v t=. After closing
|
||||||
this =.org= file, deploy them as indicated earlier.
|
this =.org= file, deploy them as indicated.
|
||||||
|
|
||||||
* Building the tests
|
* Building the tests
|
||||||
|
|
||||||
** Building file =pytest.ini=
|
** Building file =pytest.ini=
|
||||||
|
|
||||||
Markers file =pytest.ini= defines and which are used in file
|
File =pytest.ini= lists markers in file =test_appendfilename.py=
|
||||||
=test_appendfilename.py= allows to constrain the run of
|
to optionally constrain =pytest= tests. Rather than to launch
|
||||||
=pytest=. Rather than to launch a check on all tests, a call
|
a check on all tests defined, a call like e.g.,
|
||||||
like e.g.,
|
|
||||||
|
|
||||||
#+begin_src bash :tangle no
|
#+begin_src bash :tangle no
|
||||||
python -m pytest -m "prepend"
|
python -m pytest -m "prepend"
|
||||||
|
|
@ -123,11 +122,13 @@ python -m pytest -m "prepend"
|
||||||
only checks those of set =prepend=. At present, tests are
|
only checks those of set =prepend=. At present, tests are
|
||||||
grouped as
|
grouped as
|
||||||
|
|
||||||
+ =default= appendfilename's default string insertions
|
#+begin_src shell :tangle pytest.ini
|
||||||
+ =prepend= corresponding to either appendfilename's optional =-p=
|
[pytest]
|
||||||
or =--prepend= flag, and
|
markers =
|
||||||
+ =smart= corresponding to appendfilename's optional
|
default: test appendfilename's default string insertion
|
||||||
=--smart-prepend= flag
|
prepend: test appendfilename's optional -p/--prepend flag
|
||||||
|
smart_prepend: test appendfilename's optional --smart-prepend flag
|
||||||
|
#+end_src
|
||||||
|
|
||||||
It is possible to run one, two, or all three groups in one run of
|
It is possible to run one, two, or all three groups in one run of
|
||||||
pytest, for instance
|
pytest, for instance
|
||||||
|
|
@ -136,16 +137,6 @@ python -m pytest -m "prepend"
|
||||||
pytest-3 test_appendfilename.py -m "default and prepend" -v
|
pytest-3 test_appendfilename.py -m "default and prepend" -v
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The content of =pytest.ini=:
|
|
||||||
|
|
||||||
#+begin_src shell :tangle pytest.ini
|
|
||||||
[pytest]
|
|
||||||
markers =
|
|
||||||
default: appendfilename's default string insertions
|
|
||||||
prepend: appendfilename's optional -p/--prepend flag
|
|
||||||
smart: appendfilename's optional --smart-prepend flag
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Building the test script
|
** Building the test script
|
||||||
|
|
||||||
*** header section
|
*** header section
|
||||||
|
|
@ -157,23 +148,23 @@ markers =
|
||||||
# author: nbehrnd@yahoo.com
|
# author: nbehrnd@yahoo.com
|
||||||
# license: GPL v3, 2022.
|
# license: GPL v3, 2022.
|
||||||
# date: 2022-01-05 (YYYY-MM-DD)
|
# date: 2022-01-05 (YYYY-MM-DD)
|
||||||
# edit: [2024-11-05 Tue]
|
# edit: [2024-11-22 Fri]
|
||||||
#
|
#
|
||||||
"""Test pad for functions by appendfilename with pytest.
|
"""Test pad for functions by appendfilename with pytest.
|
||||||
|
|
||||||
Initially written for Python 3.9.9 and pytest 6.2.4 and recently update
|
Initially written for Python 3.9.9 and pytest 6.2.4 and recently update
|
||||||
for Python 3.12.6/pytest 8.3.3, this script provides a programmatic check
|
for Python 3.12.6/pytest 8.3.3, this script provides a programmatic check
|
||||||
of functions offered by appendfilename. Deposit this script in the root of
|
of functions offered by appendfilename. Deposit this script in the root
|
||||||
the folder fetched and unzipped from PyPi or GitHub. Create a virtual
|
of the folder fetched and unzipped from PyPi or GitHub. Create a virtual
|
||||||
environment for Python, e.g. by
|
environment for Python, e.g. by
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
python -m venv sup
|
python -m venv sup
|
||||||
```
|
```
|
||||||
|
|
||||||
In the activated virtual environment, ensure the dependencies are met -
|
In the activated virtual environment, resolve the dependencies - either by
|
||||||
either by `pip install pyreadline3 pytest`, or `pip install -r requirements.txt`
|
`pip install pyreadline3 pytest`, or `pip install -r requirements.txt` -
|
||||||
- and launch the tests by
|
and launch the tests by
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
python -m pytest
|
python -m pytest
|
||||||
|
|
@ -182,33 +173,38 @@ python -m pytest
|
||||||
As a reminder, the following optional pytest flags may be useful to obtain
|
As a reminder, the following optional pytest flags may be useful to obtain
|
||||||
a report tailored to your needs:
|
a report tailored to your needs:
|
||||||
|
|
||||||
- `-x` exits right after the first failing test (reported by `E` instead of `.`)
|
- `-x` exit after the first failing test (reported by `E` instead of `.`)
|
||||||
- `-v` provide a more verbose output
|
- `-v` provide a more verbose output
|
||||||
- `-s` equally report the test criterion, e.g. the queried file name
|
- `-s` equally report the test criterion, e.g. the queried file name
|
||||||
|
|
||||||
|
Equally keep in mind you can constrain pytest tests. Labels assigned are
|
||||||
|
|
||||||
|
- default: test appendfilename's default string insertion
|
||||||
|
- prepend: test appendfilename's optional -p/--prepend flag
|
||||||
|
- smart_prepend: test appendfilename's optional --smart-prepend flag
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
PROGRAM = os.path.join("appendfilename", "__init__.py") # Cross-platform path
|
PROGRAM = os.path.join("appendfilename", "__init__.py")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** appendfilename, default position
|
*** appendfilename, default position
|
||||||
|
|
||||||
Departing with file =test.txt=, appendfile's addition of =example= should
|
Departing from e.g., file =2021-12-31_test.txt=, appendfile's addition of
|
||||||
yield =test example.txt=.
|
=example= should yield =2021-12-31_test example.txt=.
|
||||||
|
|
||||||
#+begin_src python :tangle test_appendfilename.py
|
#+begin_src python :tangle test_appendfilename.py
|
||||||
# The following section tests the applications default pattern where a string
|
# The following section tests the applications default pattern where a
|
||||||
# is added to the file name, just prior to the file's file extension. The
|
# string is added to the file name, just prior to the file's file
|
||||||
# permutation of the three arguments and their levels defines 120 tests.
|
# extension. The permutations of the arguments define 120 tests.
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
||||||
|
|
@ -228,11 +224,14 @@ arg3_values = [
|
||||||
"--separator '='",
|
"--separator '='",
|
||||||
"--separator '-'"
|
"--separator '-'"
|
||||||
]
|
]
|
||||||
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
# Note: In Windows 10, the check with pytest and `*` as separator fails
|
||||||
|
# because it is not a permitted character in a file name there. See
|
||||||
|
# <https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file>
|
||||||
|
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.default
|
@pytest.mark.default
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
||||||
def test_append(arg1, arg2, arg3):
|
def test_append(arg1, arg2, arg3):
|
||||||
|
|
@ -249,7 +248,7 @@ def test_append(arg1, arg2, arg3):
|
||||||
# run the test to be tested:
|
# run the test to be tested:
|
||||||
full_command = ["python", PROGRAM, arg1
|
full_command = ["python", PROGRAM, arg1
|
||||||
] + shlex.split(arg2) + shlex.split(arg3)
|
] + shlex.split(arg2) + shlex.split(arg3)
|
||||||
subprocess.run(full_command, text = True, check = True)
|
subprocess.run(full_command, text=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be tested:
|
# construct the new file name to be tested:
|
||||||
if len(shlex.split(arg3)) == 0:
|
if len(shlex.split(arg3)) == 0:
|
||||||
|
|
@ -258,9 +257,8 @@ def test_append(arg1, arg2, arg3):
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
new_filename = "".join(
|
new_filename = "".join(
|
||||||
[ arg1[:-4], separator,
|
[arg1[:-4], separator, shlex.split(arg2)[1], ".txt"])
|
||||||
shlex.split(arg2)[1], ".txt" ])
|
print(f"test criterion: {new_filename}") # for an optional `pytest -s`
|
||||||
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
assert os.path.isfile(new_filename)
|
assert os.path.isfile(new_filename)
|
||||||
|
|
@ -278,9 +276,10 @@ def test_append(arg1, arg2, arg3):
|
||||||
|
|
||||||
#+begin_src python :tangle test_appendfilename.py
|
#+begin_src python :tangle test_appendfilename.py
|
||||||
|
|
||||||
# The following section is about tests to prepend a user defined string and
|
# The following section is about tests to prepend a user defined string
|
||||||
# an adjustable separator to the original file name of the file submitted. By
|
# and an adjustable separator to the original file name of the submitted
|
||||||
# permutation of the parameter's levels, this defines 240 tests.
|
# file. The permutation of the parameters defines 240 tests.
|
||||||
|
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
"test.txt", "2021-12-31_test.txt", "2021-12-31T18.48.22_test.txt"
|
||||||
|
|
@ -309,6 +308,7 @@ arg4_values = [
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values, arg4_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values, arg4_values))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.prepend
|
@pytest.mark.prepend
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3, arg4", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3, arg4", test_cases)
|
||||||
def test_prepend(arg1, arg2, arg3, arg4):
|
def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
|
|
@ -327,7 +327,7 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
full_command = [
|
full_command = [
|
||||||
"python", PROGRAM, arg1
|
"python", PROGRAM, arg1
|
||||||
] + shlex.split(arg2) + shlex.split(arg3) + shlex.split(arg4)
|
] + shlex.split(arg2) + shlex.split(arg3) + shlex.split(arg4)
|
||||||
subprocess.run(full_command, text = True, check = True)
|
subprocess.run(full_command, text=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be tested:
|
# construct the new file name to be tested:
|
||||||
if len(shlex.split(arg3)) == 0:
|
if len(shlex.split(arg3)) == 0:
|
||||||
|
|
@ -335,7 +335,7 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
else:
|
else:
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
new_filename = "".join( [ shlex.split(arg2)[1], separator, arg1 ] )
|
new_filename = "".join([shlex.split(arg2)[1], separator, arg1])
|
||||||
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
print(f"test criterion: {new_filename}") # visible by optional `pytest -s`
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
|
|
@ -363,12 +363,13 @@ def test_prepend(arg1, arg2, arg3, arg4):
|
||||||
# This section tests the insertion of a string into the file's file name
|
# This section tests the insertion of a string into the file's file name
|
||||||
# just after the file's time or date stamp as provided `date2name`.
|
# just after the file's time or date stamp as provided `date2name`.
|
||||||
|
|
||||||
|
|
||||||
arg1_values = [
|
arg1_values = [
|
||||||
"2021-12-31T18.48.22_test.txt",
|
"2021-12-31T18.48.22_test.txt",
|
||||||
"2021-12-31_test.txt",
|
"2021-12-31_test.txt",
|
||||||
# "20211231_test.txt", # by now `20211231_test.txt` -> 20211231_test ping.txt
|
# "20211231_test.txt", # by now `20211231_test.txt` -> 20211231_test ping.txt
|
||||||
# "2021-12_test.txt", # by now `2021-12_test.txt` -> `2021-12_test ping.txt`
|
# "2021-12_test.txt", # by now `2021-12_test.txt` -> `2021-12_test ping.txt`
|
||||||
# "211231_test.txt" # by now `211231_test.txt` -> `211231_test ping.txt`
|
# "211231_test.txt" # by now `211231_test.txt` -> `211231_test ping.txt`
|
||||||
]
|
]
|
||||||
arg2_values = [
|
arg2_values = [
|
||||||
"-t book",
|
"-t book",
|
||||||
|
|
@ -378,15 +379,15 @@ arg2_values = [
|
||||||
]
|
]
|
||||||
arg3_values = [
|
arg3_values = [
|
||||||
"", # i.e. fall back to default single space
|
"", # i.e. fall back to default single space
|
||||||
# "--separator '!'",
|
# "--separator '!'",
|
||||||
# "--separator '@'",
|
# "--separator '@'",
|
||||||
# "--separator '#'",
|
# "--separator '#'",
|
||||||
# "--separator '$'",
|
# "--separator '$'",
|
||||||
# "--separator '%'",
|
# "--separator '%'",
|
||||||
# "--separator '_'",
|
# "--separator '_'",
|
||||||
# "--separator '+'",
|
# "--separator '+'",
|
||||||
# "--separator '='",
|
# "--separator '='",
|
||||||
# "--separator '-'"
|
# "--separator '-'"
|
||||||
]
|
]
|
||||||
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
# Note: The check with pytest and `*` as separator in Windows 10 fails.
|
||||||
# Contrasting to Linux Debian 13, a `pytest` in Windows 10 revealed every
|
# Contrasting to Linux Debian 13, a `pytest` in Windows 10 revealed every
|
||||||
|
|
@ -395,7 +396,8 @@ arg3_values = [
|
||||||
# create the permutations:
|
# create the permutations:
|
||||||
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
test_cases = list(product(arg1_values, arg2_values, arg3_values))
|
||||||
|
|
||||||
@pytest.mark.smart
|
|
||||||
|
@pytest.mark.smart_prepend
|
||||||
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
@pytest.mark.parametrize("arg1, arg2, arg3", test_cases)
|
||||||
def test_smart_prepend(arg1, arg2, arg3):
|
def test_smart_prepend(arg1, arg2, arg3):
|
||||||
"""test the insertion of a new string just past the time stamp
|
"""test the insertion of a new string just past the time stamp
|
||||||
|
|
@ -404,18 +406,18 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
arg2 the text string to be added
|
arg2 the text string to be added
|
||||||
arg3 the separator (at least in Windows 10, do not use `*`
|
arg3 the separator (at least in Windows 10, do not use `*`
|
||||||
"""
|
"""
|
||||||
time_stamp = ""
|
timestamp = ""
|
||||||
time_stamp_separator = ""
|
# timestamp_separator = ""
|
||||||
old_filename_no_timestamp = ""
|
old_filename_no_timestamp = ""
|
||||||
|
|
||||||
# create a test file:
|
# create a test file:
|
||||||
with open(arg1, mode="w", encoding="utf-8") as newfile:
|
with open(arg1, mode="w", encoding="utf-8") as newfile:
|
||||||
newfile.write("this is a placeholder\n")
|
newfile.write("this is a placeholder\n")
|
||||||
|
|
||||||
#run `appendfilename` on this test file
|
# run `appendfilename` on this test file
|
||||||
run_appendfilename = " ".join(
|
run_appendfilename = " ".join(
|
||||||
["python", PROGRAM, arg1, arg2, arg3, " --smart-prepend"])
|
["python", PROGRAM, arg1, arg2, arg3, " --smart-prepend"])
|
||||||
subprocess.run(run_appendfilename, shell=True, check = True)
|
subprocess.run(run_appendfilename, shell=True, check=True)
|
||||||
|
|
||||||
# construct the new file name to be testedt:
|
# construct the new file name to be testedt:
|
||||||
old_filename = arg1
|
old_filename = arg1
|
||||||
|
|
@ -426,7 +428,7 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
else:
|
else:
|
||||||
separator = shlex.split(arg3)[1]
|
separator = shlex.split(arg3)[1]
|
||||||
|
|
||||||
# Time stamps `date2name` provides can be either one of five formats
|
# Timestamps `date2name` provides can be either one of five formats
|
||||||
#
|
#
|
||||||
# YYYY-MM-DDTHH.MM.SS `--withtime`
|
# YYYY-MM-DDTHH.MM.SS `--withtime`
|
||||||
# YYYY-MM-DD default
|
# YYYY-MM-DD default
|
||||||
|
|
@ -442,42 +444,39 @@ def test_smart_prepend(arg1, arg2, arg3):
|
||||||
# https://github.com/novoid/appendfilename/issues/15
|
# https://github.com/novoid/appendfilename/issues/15
|
||||||
# https://github.com/novoid/appendfilename/issues/16
|
# https://github.com/novoid/appendfilename/issues/16
|
||||||
|
|
||||||
# pattern `--with-time`
|
patterns = [
|
||||||
if re.search(r"^\d{4}-[012]\d-[0-3]\dT[012]\d\.[0-5]\d\.[0-5]\d", old_filename):
|
r"^\d{4}-[012]\d-[0-3]\dT[012]\d\.[0-5]\d\.[0-5]\d",
|
||||||
time_stamp = old_filename[:19]
|
r"^\d{4}-[012]\d-[0-3]\d",
|
||||||
time_stamp_separator = old_filename[19]
|
r"^\d{4}[012]\d[0-3]\d",
|
||||||
old_filename_no_timestamp = old_filename[20:]
|
r"^\d{4}-[012]\d",
|
||||||
|
r"^\d{2}[012]\d[0-3]\d"
|
||||||
|
]
|
||||||
|
|
||||||
# default pattern
|
for pattern in patterns:
|
||||||
elif re.search(r"^\d{4}-[012]\d-[0-3]\d", old_filename):
|
match = re.search(pattern, old_filename)
|
||||||
time_stamp = old_filename[:10]
|
if match:
|
||||||
time_stamp_separator = old_filename[10]
|
timestamp = re.findall(pattern, old_filename)[0]
|
||||||
old_filename_no_timestamp = old_filename[11:]
|
timestamp_separator = str(old_filename)[len(timestamp)]
|
||||||
|
old_filename_no_timestamp = old_filename[len(timestamp) + 1:]
|
||||||
|
|
||||||
# pattern `--compact` # currently fails
|
print("\n\ntest of option smart-prepend:") # `pytest -s` diagnosis
|
||||||
elif re.search(r"^\d{4}[012]\d[0-3]\d", old_filename):
|
print("old_filename:")
|
||||||
time_stamp = old_filename[:8]
|
print(old_filename)
|
||||||
time_stamp_separator = old_filename[8]
|
print("timestamp, timestamp_separator, old_filename_no_timestamp")
|
||||||
old_filename_no_timestamp = old_filename[9:]
|
print(timestamp)
|
||||||
|
print(timestamp_separator)
|
||||||
|
print(old_filename_no_timestamp)
|
||||||
|
|
||||||
# pattern `--month` # currently fails
|
break
|
||||||
elif re.search(r"^\d{4}-[012]\d", old_filename):
|
|
||||||
time_stamp = old_filename[:7]
|
|
||||||
time_stamp_separator = old_filename[7]
|
|
||||||
old_filename_no_timestamp = old_filename[8:]
|
|
||||||
|
|
||||||
# pattern `--short` # currently fails
|
new_filename = "".join([
|
||||||
elif re.search(r"^\d{4}[012]\d[0-3]\d", old_filename):
|
timestamp, # timestamp_separator,
|
||||||
time_stamp = old_filename[:6]
|
|
||||||
time_stamp_separator = old_filename[6]
|
|
||||||
old_filename_no_timestamp = old_filename[7:]
|
|
||||||
|
|
||||||
new_filename = "".join([time_stamp, #time_stamp_separator,
|
|
||||||
separator, shlex.split(arg2)[1], separator,
|
separator, shlex.split(arg2)[1], separator,
|
||||||
old_filename_no_timestamp ])
|
old_filename_no_timestamp
|
||||||
|
])
|
||||||
|
|
||||||
# is the new file present?
|
# is the new file present?
|
||||||
print("\nnew_filename") # optional check for `pytest -s`
|
print("new_filename") # optional check for `pytest -s`
|
||||||
print(new_filename)
|
print(new_filename)
|
||||||
assert os.path.isfile(new_filename)
|
assert os.path.isfile(new_filename)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue