mirror of
https://github.com/JockeTF/fimfarchive.git
synced 2024-11-22 05:17:59 +01:00
Add meta format mapper
This commit is contained in:
parent
478b2e7080
commit
4ee0824230
2 changed files with 85 additions and 3 deletions
|
@ -24,11 +24,12 @@ Mappers for Fimfarchive.
|
|||
|
||||
import os
|
||||
from abc import abstractmethod
|
||||
from typing import Generic, Optional, TypeVar
|
||||
from typing import Dict, Generic, Optional, Set, TypeVar
|
||||
|
||||
from arrow import api as arrow, Arrow
|
||||
|
||||
from fimfarchive.exceptions import InvalidStoryError
|
||||
from fimfarchive.flavors import MetaFormat
|
||||
from fimfarchive.stories import Story
|
||||
|
||||
|
||||
|
@ -115,3 +116,24 @@ class StoryPathMapper(Mapper[str]):
|
|||
key = str(story.key)
|
||||
|
||||
return os.path.join(directory, key)
|
||||
|
||||
|
||||
class MetaFormatMapper(Mapper[Optional[MetaFormat]]):
|
||||
"""
|
||||
Guesses the meta format of stories.
|
||||
"""
|
||||
spec: Dict[MetaFormat, Set[str]] = {
|
||||
MetaFormat.ALPHA: {'likes', 'dislikes', 'words'},
|
||||
MetaFormat.BETA: {'num_likes', 'num_dislikes', 'num_words'},
|
||||
}
|
||||
|
||||
def __call__(self, story: Story) -> Optional[MetaFormat]:
|
||||
items = self.spec.items()
|
||||
meta = set(story.meta.keys())
|
||||
|
||||
matches = {fmt for fmt, spec in items if spec & meta}
|
||||
|
||||
if len(matches) == 1:
|
||||
return next(iter(matches))
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -23,12 +23,16 @@ Mapper tests.
|
|||
|
||||
|
||||
import os
|
||||
from typing import no_type_check, Dict, Any
|
||||
from unittest.mock import patch, MagicMock, PropertyMock
|
||||
|
||||
import pytest
|
||||
|
||||
from fimfarchive.exceptions import InvalidStoryError
|
||||
from fimfarchive.mappers import StaticMapper, StoryDateMapper, StoryPathMapper
|
||||
from fimfarchive.flavors import MetaFormat
|
||||
from fimfarchive.mappers import (
|
||||
MetaFormatMapper, StaticMapper, StoryDateMapper, StoryPathMapper
|
||||
)
|
||||
from fimfarchive.stories import Story
|
||||
|
||||
|
||||
|
@ -108,7 +112,7 @@ class TestStoryDateMapper:
|
|||
"""
|
||||
Tests `None` is returned when meta contains no dates.
|
||||
"""
|
||||
meta = {
|
||||
meta: Dict[str, Any] = {
|
||||
CHAPTERS: [
|
||||
dict(),
|
||||
dict(),
|
||||
|
@ -259,6 +263,7 @@ class TestStoryPathMapper:
|
|||
|
||||
assert mapper(story) == path
|
||||
|
||||
@no_type_check
|
||||
def test_casts_values(self, tmpdir, story):
|
||||
"""
|
||||
Tests casts all values to string when joining.
|
||||
|
@ -274,3 +279,58 @@ class TestStoryPathMapper:
|
|||
assert mapper(story) == os.path.join('dir', 'key')
|
||||
assert directory.__str__.called_once_with()
|
||||
assert story.key.__str__.called_once_with()
|
||||
|
||||
|
||||
class TestMetaFormatMapper:
|
||||
"""
|
||||
MetaFormatMapper tests.
|
||||
"""
|
||||
|
||||
@pytest.fixture
|
||||
def mapper(self):
|
||||
"""
|
||||
Returns a meta format mapper instance.
|
||||
"""
|
||||
return MetaFormatMapper()
|
||||
|
||||
@pytest.fixture(params=['likes', 'dislikes', 'words'])
|
||||
def alpha(self, request):
|
||||
"""
|
||||
Returns an alpha meta key.
|
||||
"""
|
||||
return request.param
|
||||
|
||||
@pytest.fixture(params=['num_likes', 'num_dislikes', 'num_words'])
|
||||
def beta(self, request):
|
||||
"""
|
||||
Returns a beta meta key.
|
||||
"""
|
||||
return request.param
|
||||
|
||||
def merge(self, story, *keys):
|
||||
"""
|
||||
Returns a story containing the requested meta keys.
|
||||
"""
|
||||
meta = {key: i for i, key in enumerate(keys, 1)}
|
||||
return story.merge(meta=meta)
|
||||
|
||||
def test_alpha_format(self, mapper, story, alpha):
|
||||
"""
|
||||
Tests alpha meta format is detected.
|
||||
"""
|
||||
story = self.merge(story, alpha, 'misc')
|
||||
assert mapper(story) == MetaFormat.ALPHA
|
||||
|
||||
def test_beta_format(self, mapper, story, beta):
|
||||
"""
|
||||
Tests beta meta format is detected.
|
||||
"""
|
||||
story = self.merge(story, beta, 'misc')
|
||||
assert mapper(story) == MetaFormat.BETA
|
||||
|
||||
def test_conflict(self, mapper, story, alpha, beta):
|
||||
"""
|
||||
Tests None is returned for conflicting meta keys.
|
||||
"""
|
||||
story = self.merge(story, alpha, beta)
|
||||
assert mapper(story) is None
|
||||
|
|
Loading…
Reference in a new issue