diff --git a/bin/ffx/test/basename_combinator_1.py b/bin/ffx/test/_basename_combinator_1.py similarity index 81% rename from bin/ffx/test/basename_combinator_1.py rename to bin/ffx/test/_basename_combinator_1.py index 0508250..dc7ba97 100644 --- a/bin/ffx/test/basename_combinator_1.py +++ b/bin/ffx/test/_basename_combinator_1.py @@ -9,14 +9,11 @@ from .basename_combinator import BasenameCombinator from .indicator_combinator import IndicatorCombinator from .label_combinator import LabelCombinator -from .title_combinator import TitleCombinator -from .site_combinator import SiteCombinator +class BasenameCombinator2(BasenameCombinator): + """documentation_site""" -class BasenameCombinator1(BasenameCombinator): - """show_indicator_group""" - - VARIANT = 'B1' + VARIANT = 'B2' # def __init__(self, SubCombinators: dict = {}, context = None): def __init__(self, context = None): @@ -25,10 +22,8 @@ class BasenameCombinator1(BasenameCombinator): self._logger = context['logger'] self._reportLogger = context['report_logger'] - # self._SubCombinators = SubCombinations - def getVariant(self): - return BasenameCombinator1.VARIANT + return BasenameCombinator2.VARIANT def getPayload(self): return '' @@ -39,7 +34,6 @@ class BasenameCombinator1(BasenameCombinator): def shouldFail(self): return False - def getYield(self): for L in LabelCombinator.getAllClassReferences(): @@ -57,7 +51,7 @@ class BasenameCombinator1(BasenameCombinator): yieldObj['variants'] = [self.getVariant(), l.getVariant()] - yieldObj['payload'] = self.getPayload() + yieldObj['payload'] = {'label': l.getPayload()} yieldObj['assertSelectors'] = ['B', 'L'] diff --git a/bin/ffx/test/_scenario_4.py b/bin/ffx/test/_scenario_4.py new file mode 100644 index 0000000..1bae6d2 --- /dev/null +++ b/bin/ffx/test/_scenario_4.py @@ -0,0 +1,147 @@ +import os, sys, click + +from .scenario import Scenario + +from ffx.test.helper import createMediaTestFile +from ffx.process import executeProcess + +from ffx.file_properties import FileProperties + +from ffx.media_descriptor import MediaDescriptor +from ffx.track_descriptor import TrackDescriptor + +from ffx.track_type import TrackType +from ffx.track_disposition import TrackDisposition + +from ffx.test.media_combinator import MediaCombinator + + + +class Scenario4(Scenario): + + def __init__(self, context): + super().__init__(context) + + def getScenario(self): + return self.__class__.__name__[8:] + + + + def job(self, yieldObj: dict): + + testContext = self._context.copy() + + identifier = yieldObj['identifier'] + variantList = yieldObj['variants'] + + variantIdentifier = '-'.join(variantList) + variantLabel = f"{self.__class__.__name__} Variant {variantIdentifier}" + + sourceMediaDescriptor: MediaDescriptor = yieldObj['payload'] + assertSelectorList: list = yieldObj['assertSelectors'] + assertFuncList = yieldObj['assertFuncs'] + shouldFail = yieldObj['shouldFail'] + + try: + jellyfinSelectorIndex = assertSelectorList.index('J') + jellyfinVariant = variantList[jellyfinSelectorIndex] + testContext['use_jellyfin'] = jellyfinVariant == 'J1' + except ValueError: + jellyfinSelectorIndex = -1 + + + if self._context['test_variant'] and variantIdentifier != self._context['test_variant']: + return + + + self._logger.debug(f"Running Job: {variantLabel}") + + # Phase 1: Setup source files + self.clearTestDirectory() + mediaFilePath = createMediaTestFile(mediaDescriptor=sourceMediaDescriptor, directory=self._testDirectory, logger=self._logger, length = 2) + +# # Phase 2: Prepare database +# + + + + # Phase 3: Run ffx + commandSequence = [sys.executable, + self._ffxExecutablePath, + 'convert', + mediaFilePath, + '--no-prompt'] + + if not testContext['use_jellyfin']: + commandSequence += ['--no-jellyfin'] + + self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}") + + out, err, rc = executeProcess(commandSequence, directory = self._testDirectory) + + if out: + self._logger.debug(f"{variantLabel}: Process output: {out}") + if rc: + self._logger.debug(f"{variantLabel}: Process returned ERROR {rc} ({err})") + + # Phase 4: Evaluate results + + try: + + jobFailed = bool(rc) + + self._logger.debug(f"{variantLabel}: Should fail: {shouldFail} / actually failed: {jobFailed}") + + assert jobFailed == shouldFail, f"Process {'failed' if jobFailed else 'did not fail'}" + + if not jobFailed: + + resultFile = os.path.join(self._testDirectory, 'media.webm') + + assert os.path.isfile(resultFile), f"Result file 'media.webm' in path '{self._testDirectory}' wasn't created" + + resultFileProperties = FileProperties(testContext, resultFile) + resultMediaDescriptor = resultFileProperties.getMediaDescriptor() + + if testContext['use_jellyfin']: + sourceMediaDescriptor.applyJellyfinOrder() + resultMediaDescriptor.applySourceIndices(sourceMediaDescriptor) + + resultMediaTracks = resultMediaDescriptor.getAllTrackDescriptors() + + for assertIndex in range(len(assertSelectorList)): + + assertSelector = assertSelectorList[assertIndex] + assertFunc = assertFuncList[assertIndex] + assertVariant = variantList[assertIndex] + + if assertSelector == 'M': + assertFunc() + for variantIndex in range(len(assertVariant)): + assert assertVariant[variantIndex].lower() == resultMediaTracks[variantIndex].getType().indicator(), f"Stream #{variantIndex} is not of type {resultMediaTracks[variantIndex].getType().label()}" + + elif assertSelector == 'AD' or assertSelector == 'AT': + assertFunc(resultMediaDescriptor.getAudioTracks()) + + elif assertSelector == 'SD' or assertSelector == 'ST': + assertFunc(resultMediaDescriptor.getSubtitleTracks()) + + elif type(assertSelector) is str: + if assertSelector == 'J': + assertFunc() + + + self._reportLogger.info(f"{variantLabel}: Test passed") + + except AssertionError as ae: + + self._reportLogger.error(f"{variantLabel}: Test FAILED ({ae})") + + + def run(self): + MC_list = MediaCombinator.getAllClassReferences() + for MC in MC_list: + self._logger.debug(f"MC={MC.__name__}") + mc = MC(context = self._context) + for y in mc.getYield(): + self.job(y) diff --git a/bin/ffx/test/basename_combinator_0.py b/bin/ffx/test/basename_combinator_0.py index 67a0bb0..5b98ba8 100644 --- a/bin/ffx/test/basename_combinator_0.py +++ b/bin/ffx/test/basename_combinator_0.py @@ -9,12 +9,10 @@ from .basename_combinator import BasenameCombinator from .indicator_combinator import IndicatorCombinator from .label_combinator import LabelCombinator -from .title_combinator import TitleCombinator -from .site_combinator import SiteCombinator class BasenameCombinator0(BasenameCombinator): - """base_indicator""" + """base[_indicator]""" VARIANT = 'B0' @@ -40,15 +38,6 @@ class BasenameCombinator0(BasenameCombinator): 'label': label, 'expectedBasename': expectedBasename} -# testParameterBasename = yieldObj['payload']['basename'] -# testParameterExtension = 'mkv' -# testParameterFilename = f"{testParameterBasename}.{testParameterExtension}" -# -# #TODO: alles in payload verpacken -# testParameterLabel = yieldObj['payload']['label'] -# testExpectedExtension = 'webm' -# testExpectedFilename = f"{testParameterBasename}.{testExpectedExtension}" - def assertFunc(self, indicator = '', label = ''): @@ -90,9 +79,6 @@ class BasenameCombinator0(BasenameCombinator): for L in LabelCombinator.getAllClassReferences(): for i in ic.getYield(): -# for S in SiteCombinator.getAllClassReferences(): -# for T in TitleCombinator.getAllClassReferences(): -# l = L(self._context) diff --git a/bin/ffx/test/basename_combinator_2.py b/bin/ffx/test/basename_combinator_2.py index d572112..32a3b52 100644 --- a/bin/ffx/test/basename_combinator_2.py +++ b/bin/ffx/test/basename_combinator_2.py @@ -10,16 +10,17 @@ from .basename_combinator import BasenameCombinator from .indicator_combinator import IndicatorCombinator from .label_combinator import LabelCombinator from .title_combinator import TitleCombinator -from .site_combinator import SiteCombinator +from .release_combinator import ReleaseCombinator +from .show_combinator import ShowCombinator + class BasenameCombinator2(BasenameCombinator): - """documentation_site""" + """show[_indicator]_group""" VARIANT = 'B2' # def __init__(self, SubCombinators: dict = {}, context = None): def __init__(self, context = None): - self._context = context self._logger = context['logger'] self._reportLogger = context['report_logger'] @@ -27,40 +28,132 @@ class BasenameCombinator2(BasenameCombinator): def getVariant(self): return BasenameCombinator2.VARIANT - def getPayload(self): - return '' +# +# SHOW_LIST = [ +# 'Boruto: Naruto Next Generations (2017)', +# 'The Rising of the Shield Hero (2019)', +# 'Scrubs - Die Anfänger (2001)' +# ] +# +# RELEASE_LIST = [ +# ".GerEngSub.AAC.1080pINDICATOR.WebDL.x264-Tanuki", +# ".German.AC3.DL.1080pINDICATOR.BluRay.x264-AST4u", +# "-720pINDICATOR" +# ] + + + def getPayload(self, + indicator = '', + label = '', + show = '', + release = ''): + + if label: + basename = label + expectedBasename = label + if indicator: + basename += f"_{indicator}" + expectedBasename += f"_{indicator}" + else: + basename = show+release + expectedBasename = basename + + return {'basename': basename, + 'label': label, + 'expectedBasename': expectedBasename} + + + def assertFunc(self, + indicator = '', + label = '', + show = '', + release = ''): + + def f(testObj: dict = {}): + + if not 'filenames' in testObj.keys(): + raise KeyError("testObj does not contain key 'filenames'") + + fNames = testObj['filenames'] + + assert len(fNames) == 1, "More than one result file was created" + + resultFilename = fNames[0] + + fTokens = resultFilename.split('.') + + resultBasename = '.'.join(fTokens[:-1]) + resultExtension = fTokens[-1] + + if not indicator and not label: + assert resultBasename == show+release, f"Result basename is not {show+release}" + elif not indicator and label: + assert resultBasename == label, f"Result basename is not {label}" + elif indicator and not label: + assert resultBasename == show+release, f"Result basename is not {show+release}" + elif indicator and label: + assert resultBasename == f"{label}_{indicator}", f"Result basename is not {label}_{indicator}" + + return f - def assertFunc(self, mediaDescriptor: MediaDescriptor): - pass def shouldFail(self): return False def getYield(self): + ic = IndicatorCombinator(self._context) + sc = ShowCombinator(self._context) + for L in LabelCombinator.getAllClassReferences(): -# for I in IndicatorCombinator.getAllClassReferences(): -# for S in SiteCombinator.getAllClassReferences(): -# for T in TitleCombinator.getAllClassReferences(): -# + for iy in ic.getYield(): + + indicator = iy['indicator'] + indicatorVariant = iy['variant'] + + rc = ReleaseCombinator(self._context, indicator=indicator) + + for sy in sc.getYield(): + for ry in rc.getYield(): + + l = L(self._context) + + show = sy['show'] + showVariant = sy['variant'] - l = L(self._context) + release = ry['release'] + releaseVariant = ry['variant'] - yieldObj = {} + yieldObj = {} - yieldObj['identifier'] = self.getIdentifier() + yieldObj['identifier'] = self.getIdentifier() - yieldObj['variants'] = [self.getVariant(), - l.getVariant()] + yieldObj['variants'] = [self.getVariant(), + l.getVariant(), + indicatorVariant, + showVariant, + releaseVariant] - yieldObj['payload'] = {'label': l.getPayload()} + yieldObj['payload'] = self.getPayload(indicator = indicator, + label = l.getPayload(), + show = show, + release = release) - yieldObj['assertSelectors'] = ['B', 'L'] + yieldObj['assertSelectors'] = ['B', 'L', 'I', 'S', 'R'] - yieldObj['assertFuncs'] = [self.assertFunc, - l.assertFunc] + yieldObj['assertFuncs'] = [self.assertFunc(indicator, + l.getPayload(), + show = show, + release = release), + l.assertFunc, + ic.assertFunc, + sc.assertFunc, + rc.assertFunc] - yieldObj['shouldFail'] = (self.shouldFail() - | l.shouldFail()) + yieldObj['shouldFail'] = (self.shouldFail() + | l.shouldFail() + | ic.shouldFail() + | sc.shouldFail() + | rc.shouldFail()) - yield yieldObj \ No newline at end of file + yield yieldObj diff --git a/bin/ffx/test/release_combinator.py b/bin/ffx/test/release_combinator.py new file mode 100644 index 0000000..8fd4e77 --- /dev/null +++ b/bin/ffx/test/release_combinator.py @@ -0,0 +1,37 @@ +class ReleaseCombinator(): + + IDENTIFIER = 'release' + + RELEASE_LIST = [ + ".GerEngSub.AAC.1080pINDICATOR.WebDL.x264-Tanuki", + ".German.AC3.DL.1080pINDICATOR.BluRay.x264-AST4u", + "-720pINDICATOR" + ] + + def __init__(self, context = None, indicator = ''): + self._context = context + self._logger = context['logger'] + self._reportLogger = context['report_logger'] + + self.__indicator = indicator + + def getIdentifier(self): + return ReleaseCombinator.IDENTIFIER + + def getPayload(self, releaseIndex): + releaseStr: str = ReleaseCombinator.RELEASE_LIST[releaseIndex] + return { + 'variant': f"R{releaseIndex}", + 'release': releaseStr.replace('INDICATOR', f".{self.__indicator}") + if self.__indicator else releaseStr.replace('INDICATOR', '') + } + + def assertFunc(self, testObj = {}): + pass + + def shouldFail(self): + return False + + def getYield(self): + for releaseIndex in range(len(ReleaseCombinator.RELEASE_LIST)): + yield self.getPayload(releaseIndex) diff --git a/bin/ffx/test/scenario_3.py b/bin/ffx/test/scenario_3.py deleted file mode 100644 index 7e0b8a5..0000000 --- a/bin/ffx/test/scenario_3.py +++ /dev/null @@ -1,15 +0,0 @@ -from .scenario import Scenario - -class Scenario3(Scenario): - - def __init__(self, context): - super().__init__(context) - - def getScenario(self): - return self.__class__.__name__[8:] - - def run(self): - pass - # self._testDirectory - - #createMediaTestFile() diff --git a/bin/ffx/test/show_combinator.py b/bin/ffx/test/show_combinator.py new file mode 100644 index 0000000..cb40cf3 --- /dev/null +++ b/bin/ffx/test/show_combinator.py @@ -0,0 +1,33 @@ +class ShowCombinator(): + + IDENTIFIER = 'show' + + SHOW_LIST = [ + 'Boruto; Naruto Next Generations (2017)', + 'The Rising of the Shield Hero (2019)', + 'Scrubs - Die Anfänger (2001)' + ] + + def __init__(self, context = None): + self._context = context + self._logger = context['logger'] + self._reportLogger = context['report_logger'] + + def getIdentifier(self): + return ShowCombinator.IDENTIFIER + + def getPayload(self, showIndex): + return { + 'variant': f"S{showIndex}", + 'show': ShowCombinator.SHOW_LIST[showIndex] + } + + def assertFunc(self, testObj = {}): + pass + + def shouldFail(self): + return False + + def getYield(self): + for showIndex in range(len(ShowCombinator.SHOW_LIST)): + yield self.getPayload(showIndex) diff --git a/bin/ffx/test/site_combinator.py b/bin/ffx/test/site_combinator.py deleted file mode 100644 index 9c83a10..0000000 --- a/bin/ffx/test/site_combinator.py +++ /dev/null @@ -1,34 +0,0 @@ -class SiteCombinator(): - - IDENTIFIER = 'site' - - SITE_LIST = [ - ".GerEngSub.AAC.1080pINDICATOR.WebDL.x264-Tanuki", - ".German.AC3.DL.1080pINDICATOR.BluRay.x264-AST4u", - "-720pINDICATOR" - ] - - def __init__(self, context = None, indicator = ''): - self._context = context - self._logger = context['logger'] - self._reportLogger = context['report_logger'] - - self.__indicator = indicator - - def getIdentifier(self): - return SiteCombinator.IDENTIFIER - - def getPayload(self, index): - site = SiteCombinator.SITE_LIST[index] - return site.replace('INDICATOR', f".{self.__indicator}") if self.__indicator else site.replace('INDICATOR', '') - - def assertFunc(self, testObj = {}): - pass - - def shouldFail(self): - return False - - def getYield(self): - - for titleIndex in len(SiteCombinator.SITE_LIST): - yield self.getPayload(titleIndex) diff --git a/bin/ffx/test/title_combinator.py b/bin/ffx/test/title_combinator.py index 002da0c..1552f3e 100644 --- a/bin/ffx/test/title_combinator.py +++ b/bin/ffx/test/title_combinator.py @@ -4,7 +4,7 @@ class TitleCombinator(): TITLE_LIST = [ 'The Sound of Space', - ' 2001: Odyssee im Weltraum (1968)', + '2001; Odyssee im Weltraum (1968)', 'Ansible 101' ] @@ -16,6 +16,12 @@ class TitleCombinator(): def getIdentifier(self): return TitleCombinator.IDENTIFIER + def getPayload(self, titleIndex): + return { + 'variant': f"S{titleIndex}", + 'show': TitleCombinator.TITLE_LIST[titleIndex] + } + def assertFunc(self, testObj = {}): pass @@ -23,6 +29,5 @@ class TitleCombinator(): return False def getYield(self): - - for title in TitleCombinator.TITLE_LIST: - yield title + for titleIndex in range(len(TitleCombinator.TITLE_LIST)): + yield self.getPayload(titleIndex)