feat: add write --clear to remove otag's tags from files

This commit is contained in:
randogoth 2026-10-24 22:24:39 +03:00
parent c1bc07ffeb
commit 8a19f5f0af
11 changed files with 193 additions and 29 deletions

116
tests/test_clear.py Normal file
View file

@ -0,0 +1,116 @@
import sys
import wave
import zipfile
import pytest
from pypdf import PdfReader, PdfWriter
import orvanitag.orvani as orvani
from orvanitag.cmd import main
from orvanitag.orvani import OrvaniTag, NoEntry
from test_ebook import FB2, OPF, make_cbz, make_epub, opf_of
from test_plugins import DOCX_CORE, make_docx
@pytest.fixture
def cwd(tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
return tmp_path
def tag_and_clear(name, plugin, *tags):
OrvaniTag().add(name, *(tags or ['#lofi']))
OrvaniTag().write_metadata(name, plugin)
OrvaniTag().write_metadata(name, plugin, clear=True)
def test_without_clear_an_untagged_file_is_refused(cwd):
(cwd / 'a.py').write_text('print(1)\n')
with pytest.raises(NoEntry):
OrvaniTag().write_metadata('a.py', 'comment')
def test_clear_pdf_keeps_other_metadata(cwd):
writer = PdfWriter()
writer.add_blank_page(72, 72)
writer.add_metadata({'/Title': 'T'})
writer.write(cwd / 'a.pdf')
tag_and_clear('a.pdf', 'pdf')
meta = PdfReader(cwd / 'a.pdf').metadata
assert '/Keywords' not in meta and meta['/Title'] == 'T'
def test_clear_docx_removes_description(cwd):
make_docx(cwd / 'a.docx')
tag_and_clear('a.docx', 'office')
with zipfile.ZipFile(cwd / 'a.docx') as z:
assert z.read('docProps/core.xml').decode() == DOCX_CORE.replace('<dc:description></dc:description>', '')
def test_clear_id3_comment(cwd):
taglib = pytest.importorskip('taglib')
with wave.open(str(cwd / 'a.wav'), 'wb') as audio:
audio.setnchannels(1)
audio.setsampwidth(2)
audio.setframerate(8000)
audio.writeframes(b'\0\0' * 800)
tag_and_clear('a.wav', 'id3')
with taglib.File(cwd / 'a.wav') as song:
assert 'COMMENT' not in song.tags
@pytest.mark.parametrize('name, source', [
('m.go', 'package main\n'),
('s.sh', '#!/bin/sh\n\necho\n'),
])
def test_clear_comment_line_restores_the_file(cwd, name, source):
(cwd / name).write_text(source)
tag_and_clear(name, 'comment')
assert (cwd / name).read_text() == source
def test_clear_ebooks(cwd):
make_epub(cwd / 'a.epub')
tag_and_clear('a.epub', 'ebook')
assert opf_of(cwd / 'a.epub') == OPF
fb2 = FB2.format(encoding='utf-8')
(cwd / 'a.fb2').write_text(fb2)
tag_and_clear('a.fb2', 'ebook')
assert (cwd / 'a.fb2').read_text() == fb2
make_cbz(cwd / 'a.cbz')
tag_and_clear('a.cbz', 'ebook')
with zipfile.ZipFile(cwd / 'a.cbz') as z:
assert z.comment == b''
def test_clear_keeps_a_foreign_cbz_comment(cwd):
make_cbz(cwd / 'a.cbz', b'{"ComicBookInfo/1.0": {}}')
OrvaniTag().write_metadata('a.cbz', 'ebook', clear=True)
with zipfile.ZipFile(cwd / 'a.cbz') as z:
assert z.comment == b'{"ComicBookInfo/1.0": {}}'
@pytest.mark.parametrize('source, cleared', [
('---\ntitle: A\n---\ntext\n', '---\ntitle: A\n---\ntext\n'),
('text\n', 'text\n'),
])
def test_clear_frontmatter(cwd, source, cleared):
(cwd / 'a.md').write_text(source)
tag_and_clear('a.md', 'frontmatter', '+p', '#lofi', 'a', 'note')
assert (cwd / 'a.md').read_text() == cleared
def test_cmd_clear_and_hint(cwd, monkeypatch, capsys):
(cwd / 'a.py').write_text('# otag: #old\nprint(1)\n')
monkeypatch.setattr(sys, 'argv', ['otag', 'w', 'comment', 'a.py'])
with pytest.raises(SystemExit):
main()
assert '--clear' in capsys.readouterr().out
monkeypatch.setattr(sys, 'argv', ['otag', 'w', '--clear', 'comment', 'a.py'])
main()
assert (cwd / 'a.py').read_text() == 'print(1)\n'
assert not (cwd / orvani.CONTEXT_FILE).exists()