From b522762168833320835f879958a323606c85af25 Mon Sep 17 00:00:00 2001 From: Taka Date: Sun, 2 Sep 2018 09:13:16 +0000 Subject: [PATCH] Added more tests for American vehicle capabilitiies. --- .../webapp/templates/vo-report.html | 7 +- .../webapp/tests/test_capabilities.py | 291 ++++++++++-------- .../webapp/tests/test_vo_reports.py | 15 +- vasl_templates/webapp/vo.py | 9 +- 4 files changed, 178 insertions(+), 144 deletions(-) diff --git a/vasl_templates/webapp/templates/vo-report.html b/vasl_templates/webapp/templates/vo-report.html index 4748522..9ba2663 100644 --- a/vasl_templates/webapp/templates/vo-report.html +++ b/vasl_templates/webapp/templates/vo-report.html @@ -38,10 +38,14 @@ $(document).ready( function () { function load_vo_listings( objs ) { // initialize + var theater = "{{THEATER}}".toUpperCase() ; var nat = "{{NATIONALITY}}" ; var year = {{YEAR}} ; var month = {{MONTH}} ; var $results = $("#results") ; + var vo_name = getUrlParam( "name" ) ; // nb: restricts the report to a single vehicle/ordnance + if ( vo_name ) + vo_name = decodeURIComponent( vo_name ).toLowerCase() ; // check if there are any vehicles/ordnance for the specified nationality if ( ! (nat in objs ) ) { @@ -61,6 +65,8 @@ function load_vo_listings( objs ) buf.push( "Capabilities", "Notes" ) ; for ( var i=0 ; i < objs[nat].length ; ++i ) { var obj = objs[nat][i] ; + if ( vo_name && obj.name.toLowerCase() != vo_name ) + continue ; buf.push( "" ) ; buf.push( "", fmtval(obj.name) ) ; if ( "{{VO_TYPE}}" === "vehicles" ) { @@ -68,7 +74,6 @@ function load_vo_listings( objs ) buf.push( "", fmtval( obj.no_if ? "" : "✓" ) ) ; buf.push( "", fmtval(make_crew_survival(obj)) ) ; } - var theater = "ETO" ; var capabilities = make_capabilities( obj, theater, year, month, true, true ) ; buf.push( "", listval(capabilities) ) ; var capabilities = make_capabilities( obj, theater, year, month, true, false ) ; diff --git a/vasl_templates/webapp/tests/test_capabilities.py b/vasl_templates/webapp/tests/test_capabilities.py index 1ac447a..305dd75 100644 --- a/vasl_templates/webapp/tests/test_capabilities.py +++ b/vasl_templates/webapp/tests/test_capabilities.py @@ -1,167 +1,192 @@ """ Test snippet generation for capabilities. """ -from vasl_templates.webapp.tests.utils import \ - init_webapp, select_tab, new_scenario, load_scenario_params, \ - find_child, wait_for_clipboard +import pytest + +from vasl_templates.webapp.tests.test_vo_reports import get_vo_report # --------------------------------------------------------------------- +@pytest.mark.skipif( + pytest.config.option.short_tests, #pylint: disable=no-member + reason = "--short-tests specified" +) #pylint: disable=too-many-statements def test_month_capabilities( webapp, webdriver ): """Test date-based capabilities that change in the middle of a year.""" - # initialize - init_webapp( webapp, webdriver ) - # Sherman III(a): WP6(J4+)† s8 - load_scenario_params( { - "scenario": { - "PLAYER_1": "russian", - }, - "ob1": { - "OB_VEHICLES_1": [ "Sherman III(a)" ], - } - } ) - _check_snippet( None, "01/01/1943", "vehicles", '"s8"' ) - _check_snippet( None, "05/31/1944", "vehicles", '"s8"' ) - _check_snippet( None, "06/01/1944", "vehicles", '"WP6\u2020" "s8"' ) - _check_snippet( None, "01/01/1945", "vehicles", '"WP6\u2020" "s8"' ) + vehicle = [ "russian", "vehicles", "Sherman III(a)" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "s8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "05/1944", "s8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "06/1944", "WP6\u2020 s8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "WP6\u2020 s8" ) # Churchill III(b): D6(J4)/7(5)† ; HE7(F3)/8(4+)† ; sD6(4+) ; sM8† - new_scenario() - load_scenario_params( { - "scenario": { - "PLAYER_1": "russian", - }, - "ob1": { - "OB_VEHICLES_1": [ "Churchill III(b)" ], - } - } ) - _check_snippet( None, "01/01/1942", "vehicles", '"sM8\u2020"' ) - _check_snippet( None, "01/31/1943", "vehicles", '"sM8\u2020"' ) - _check_snippet( None, "02/01/1943", "vehicles", '"HE7\u2020" "sM8\u2020"' ) - _check_snippet( None, "05/31/1944", "vehicles", '"HE8\u2020" "sD6" "sM8\u2020"' ) - _check_snippet( None, "06/01/1944", "vehicles", '"D6\u2020" "HE8\u2020" "sD6" "sM8\u2020"' ) - _check_snippet( None, "01/01/1945", "vehicles", '"D7\u2020" "HE8\u2020" "sD6" "sM8\u2020"' ) + vehicle = [ "russian", "vehicles", "Churchill III(b)" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1942", "sM8\u2020" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1943", "sM8\u2020" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "02/1943", "HE7\u2020 sM8\u2020" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "05/1944", "HE8\u2020 sD6 sM8\u2020" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "06/1944", "D6\u2020 HE8\u2020 sD6 sM8\u2020" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "D7\u2020 HE8\u2020 sD6 sM8\u2020" ) # M3A1 37mm AT Gun: NT, QSU, C7(A2+)†1 - new_scenario() - load_scenario_params( { - "scenario": { - "PLAYER_1": "american", - }, - "ob1": { - "OB_ORDNANCE_1": [ "M3A1 37mm AT Gun" ], - } - } ) - _check_snippet( None, "01/01/1941", "ordnance", '"NT" "QSU"' ) - _check_snippet( None, "07/31/1942", "ordnance", '"NT" "QSU"' ) - _check_snippet( None, "08/01/1942", "ordnance", '"NT" "QSU" "C7\u20201"' ) + ordnance = [ "american", "ordnance", "M3A1 37mm AT Gun" ] + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "12/1941", "NT QSU" ) + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "07/1942", "NT QSU" ) + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "08/1942", "NT QSU C7\u20201" ) # M1 57mm AT Gun: NT, QSU, HE7(J4E)/7(5)†, D4(J4+E)† - new_scenario() - load_scenario_params( { - "scenario": { - "SCENARIO_THEATER": "ETO", - "PLAYER_1": "american", - }, - "ob1": { - "OB_ORDNANCE_1": [ "M1 57mm AT Gun" ], - } - } ) - _check_snippet( None, "01/01/1943", "ordnance", '"NT" "QSU"' ) - _check_snippet( None, "05/31/1944", "ordnance", '"NT" "QSU"' ) - _check_snippet( None, "06/01/1944", "ordnance", '"NT" "QSU" "D4\u2020" "HE7\u2020"' ) - _check_snippet( None, "01/01/1945", "ordnance", '"NT" "QSU" "D4\u2020" "HE7\u2020"' ) - _check_snippet( "PTO", "01/01/1945", "ordnance", '"NT" "QSU"' ) + ordnance = [ "american", "ordnance", "M1 57mm AT Gun" ] + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "12/1943", "NT QSU" ) + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "05/1944", "NT QSU" ) + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "06/1944", "NT QSU D4\u2020 HE7\u2020" ) + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "01/1945", "NT QSU D4\u2020 HE7\u2020" ) + _check_capabilities( webdriver, webapp, *ordnance, "PTO", "01/1945", "NT QSU" ) + + # M3: C7(A2+)†2 + vehicle = [ "american", "vehicles", "M3" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1941", "n/a", (1,3) ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "07/1942", "n/a", (1,3) ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "08/1942", "C7\u20202", (1,3) ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1943", "C7\u20202", (1,3) ) + + # M4/M4A1/M4A2/M4A3: WP7(J4+)†3 s5(J4+) sM5(4+) + for vo_name in ("M4","M4A1","M4A2","M4A3"): + vehicle = [ "american", "vehicles", vo_name ] + ref = "\u2020{}".format( 2 if vo_name == "M4A2" else 3 ) + sM = 4 if vo_name == "M4A3" else 5 + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "n/a" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "05/1944", "sM{}".format(sM) ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "06/1944", "WP7{} s5 sM{}".format(ref,sM) ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "WP7{} s5 sM{}".format(ref,sM) ) + + # M4A3E2 (L): A4(4)/5(5), s5(5) + vehicle = [ "american", "vehicles", "M4A3E2 (L)" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1944", "A4 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1944", "A4 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "A5 s5 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1946", "A5 s5 sM8" ) + + # M4A1(76)W & M4A3(76)W: A4(A4)/5(5)†2, s5(5) + for vo_name in ("M4A1(76)W","M4A3(76)W"): + vehicle = [ "american", "vehicles", vo_name ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "07/1944", "sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "08/1944", "A4\u20202 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "A5\u20202 s5 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1946", "A5\u20202 s5 sM8" ) + + # Sherman Crab: s5(J4+); WP7(J4+)†2 + vehicle = [ "american", "vehicles", "Sherman Crab" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "sM4" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "05/1944", "sM4" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "06/1944", "WP7\u20202 s5 sM4" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "WP7\u20202 s5 sM4" ) + + # M8 HMC: C4(4+)†1 + vehicle = [ "american", "vehicles", "M8 HMC" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "H9 WP9" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1944", "C4\u20201 H9 WP9" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "C4\u20201 H9 WP9" ) # --------------------------------------------------------------------- +@pytest.mark.skipif( + pytest.config.option.short_tests, #pylint: disable=no-member + reason = "--short-tests specified" +) def test_scenario_theater( webapp, webdriver ): """Test ETO/PTO-only capabilities.""" - # initialize - init_webapp( webapp, webdriver ) - # M2A1 105mm Howitzer: C7(4+P)†1 - load_scenario_params( { - "scenario": { - "PLAYER_1": "american", - }, - "ob1": { - "OB_ORDNANCE_1": [ "M2A1 105mm Howitzer" ], - } - } ) - _check_snippet( "ETO", "01/01/1940", "ordnance", '"NT" "H6" "WP8" "s7"' ) - _check_snippet( "ETO", "01/01/1944", "ordnance", '"NT" "H6" "WP8" "s7"' ) - _check_snippet( "ETO", "01/01/1945", "ordnance", '"NT" "H6" "WP8" "s7"' ) - _check_snippet( "PTO", "01/01/1940", "ordnance", '"NT" "H6" "WP8" "s7"' ) - _check_snippet( "PTO", "01/01/1944", "ordnance", '"NT" "C7\u20201" "H6" "WP8" "s7"' ) - _check_snippet( "PTO", "01/01/1945", "ordnance", '"NT" "C7\u20201" "H6" "WP8" "s7"' ) + ordnance = [ "american", "ordnance", "M2A1 105mm Howitzer" ] + _check_capabilities( webdriver, webapp, *ordnance , "ETO", "12/1943", "NT H6 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance , "ETO", "01/1944", "NT H6 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance , "ETO", "01/1945", "NT H6 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance , "PTO", "12/1943", "NT H6 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance , "PTO", "01/1944", "NT C7\u20201 H6 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance , "PTO", "01/1945", "NT C7\u20201 H6 WP8 s7" ) # M3 105mm Howitzer: C7(P)†1 - new_scenario() - load_scenario_params( { - "scenario": { - "PLAYER_1": "american", - }, - "ob1": { - "OB_ORDNANCE_1": [ "M3 105mm Howitzer" ], - } - } ) - _check_snippet( "ETO", "01/01/1940", "ordnance", '"NT" "H7" "WP8" "s7"' ) - _check_snippet( "PTO", "01/01/1940", "ordnance", '"NT" "C7\u20201" "H7" "WP8" "s7"' ) + ordnance = [ "american", "ordnance", "M3 105mm Howitzer" ] + _check_capabilities( webdriver, webapp, *ordnance, "ETO", "01/1940", "NT H7 WP8 s7" ) + _check_capabilities( webdriver, webapp, *ordnance, "PTO", "01/1940", "NT C7\u20201 H7 WP8 s7" ) + + # M2A4: C10(P)†1 + vehicle = [ "american", "vehicles", "M2A4" ] + _check_capabilities( webdriver, webapp, *vehicle, "PTO", "01/1940", "C10\u20201" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1940", "n/a" ) + + # M4(105) & M4A3(105): C7P†1 + for vo_name in ("M4(105)","M4A3(105)"): + vehicle = [ "american", "vehicles", vo_name ] + _check_capabilities( webdriver, webapp, *vehicle, "PTO", "01/1940", "C7\u20201 H9 WP9 s7 sM8" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1940", "H9 WP9 s7 sM8" ) # NOTE: We do a bit of hackery for the APCR specification for the M10 GMC and M18 GMC, # to flag them as ETO-only, so we make sure everything's working properly here. # M10 GMC: A(E)5(A4)/6(5)†1 - new_scenario() - load_scenario_params( { - "scenario": { - "PLAYER_1": "american", - }, - "ob1": { - "OB_VEHICLES_1": [ "M10 GMC" ], - } - } ) - _check_snippet( "ETO", "07/31/1944", "vehicles", '"sP5"' ) - _check_snippet( "ETO", "08/01/1944", "vehicles", '"A5\u20201" "sP5"' ) - _check_snippet( "ETO", "01/01/1945", "vehicles", '"A6\u20201" "s5" "sP5"' ) - _check_snippet( "other", "01/01/1945", "vehicles", '"s5" "sP5"' ) + vehicle = [ "american", "vehicles", "M10 GMC" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "07/1944", "sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "08/1944", "A5\u20201 sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "A6\u20201 s5 sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "other", "01/1945", "s5 sP5" ) # M18 GMC: A(E)5(4)/6(5)†1 - new_scenario() - load_scenario_params( { - "scenario": { - "PLAYER_1": "american", - }, - "ob1": { - "OB_VEHICLES_1": [ "M18 GMC" ], - } - } ) - _check_snippet( "ETO", "12/31/1943", "vehicles", '"sP5"' ) - _check_snippet( "ETO", "01/01/1944", "vehicles", '"A5\u20201" "sP5"' ) - _check_snippet( "ETO", "01/01/1945", "vehicles", '"A6\u20201" "s5" "sP5"' ) - _check_snippet( "other", "01/01/1945", "vehicles", '"s5" "sP5"' ) - + vehicle = [ "american", "vehicles", "M18 GMC" ] + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "12/1943", "sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1944", "A5\u20201 sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1945", "A6\u20201 s5 sP5" ) + _check_capabilities( webdriver, webapp, *vehicle, "other", "01/1945", "s5 sP5" ) + + # M7 HMC: C7(P)†1 + vehicle = [ "american", "vehicles", "M7 HMC" ] + _check_capabilities( webdriver, webapp, *vehicle, "PTO", "01/1940", "C7\u20201 H7 WP8 s7" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1940", "H7 WP8 s7" ) + + # LVT(A)1: C10(P)†2 + vehicle = [ "american", "vehicles", "LVT(A)1" ] + _check_capabilities( webdriver, webapp, *vehicle, "PTO", "01/1940", "C10\u20202" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1940", "n/a" ) + + # LVT(A)4: C7(P)†3 + vehicle = [ "american", "vehicles", "LVT(A)4" ] + _check_capabilities( webdriver, webapp, *vehicle, "PTO", "01/1940", "C7\u20203 H8 WP9" ) + _check_capabilities( webdriver, webapp, *vehicle, "ETO", "01/1940", "H8 WP9" ) # --------------------------------------------------------------------- -def _check_snippet( scenario_theater, scenario_date, vo_type, expected ): - """Test snippet generation.""" - - # update the scenario parameters - params = { - "scenario": { - "SCENARIO_DATE": scenario_date, - } - } - if scenario_theater: - params["scenario"]["SCENARIO_THEATER"] = scenario_theater - load_scenario_params( params ) - - # generate and check the snippet - select_tab( "ob1" ) - btn = find_child( "button.generate[data-id='ob_{}_1']".format( vo_type ) ) - btn.click() - wait_for_clipboard( 2, "capabilities: {}".format(expected), contains=True ) +def _check_capabilities( webdriver, webapp, + nat, vo_type, vo_name, scenario_theater, scenario_date, + expected, row=None +): #pylint: disable=too-many-arguments + """Check the vehicle/ordnance capabilities for the specified parameters. + + NOTE: We're only interested in checking the generated capabilities, not testing the UI, + so we use a V/O report to get the information out of the webapp, which is significantly faster. + """ + + # FUDGE! There are a few vehicles with the same name :-/ + if row: + row_no, expected_rows = row + else: + row_no = expected_rows = 1 + + # generate the V/O report + month, year = scenario_date.split( "/" ) + results = get_vo_report( webapp, webdriver, scenario_theater, nat, vo_type, year, month, name=vo_name ) + assert len(results) == 1+expected_rows + + # check the capabilities + if vo_type == "vehicles": + assert "Capabilities" in results[0][4] + capabilities = results[row_no][5] + elif vo_type == "ordnance": + assert "Capabilities" in results[0][1] + capabilities = results[row_no][2] + else: + assert False + assert capabilities == expected diff --git a/vasl_templates/webapp/tests/test_vo_reports.py b/vasl_templates/webapp/tests/test_vo_reports.py index 0e0ccda..a29671b 100644 --- a/vasl_templates/webapp/tests/test_vo_reports.py +++ b/vasl_templates/webapp/tests/test_vo_reports.py @@ -18,7 +18,6 @@ def test_vo_reports( webapp, webdriver ): """Check the vehicle/ordnance reports.""" # initialize - test_utils._webdriver = webdriver #pylint: disable=protected-access check_dir = os.path.join( os.path.split(__file__)[0], "fixtures/vo-reports/" ) save_dir = None # nb: define this to save the generated reports @@ -43,7 +42,7 @@ def test_vo_reports( webapp, webdriver ): # get the next report buf = io.StringIO() - results = get_vo_report( webapp, webdriver, nat, vo_type, year ) + results = get_vo_report( webapp, webdriver, "ETO", nat, vo_type, year, 1 ) # FUDGE! The "capabilities" and "notes" columns span 2 columns each, # so we add dummy header columns to stop tabulate from getting confused :-/ @@ -80,7 +79,7 @@ def test_vo_reports( webapp, webdriver ): # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def get_vo_report( webapp, webdriver, nat, vo_type, year ): +def get_vo_report( webapp, webdriver, theater, nat, vo_type, year, month, name=None ): """Get a vehicle/ordnance report. NOTE: We can't get the V/O report to return its results as, say, plain-text, for easy checking, @@ -88,10 +87,14 @@ def get_vo_report( webapp, webdriver, nat, vo_type, year ): the results are ready i.e. Selenium, not wget :-/ """ + # nb: in case the caller hasn't called init_webapp() + test_utils._webdriver = webdriver #pylint: disable=protected-access + # initialize - webdriver.get( - webapp.url_for( "get_vo_report", nat=nat, vo_type=vo_type, year=year ) - ) + url = webapp.url_for( "get_vo_report", theater=theater, nat=nat, vo_type=vo_type, year=year, month=month ) + if name: + url += "?&name={}".format( name ) + webdriver.get( url ) wait_for( 2, lambda: find_child("#results").is_displayed() ) def tidy( cell ): diff --git a/vasl_templates/webapp/vo.py b/vasl_templates/webapp/vo.py index 7759b82..0e1574c 100644 --- a/vasl_templates/webapp/vo.py +++ b/vasl_templates/webapp/vo.py @@ -46,18 +46,19 @@ def _do_get_listings( listings_type ): # --------------------------------------------------------------------- -@app.route( "///", defaults={"month":1} ) -@app.route( "////" ) -def get_vo_report( nat, vo_type, year, month ): +@app.route( "////", defaults={"month":1} ) +@app.route( "/////" ) +def get_vo_report( theater, nat, vo_type, year, month ): """Get a vehicle/ordnance report.""" # generate the vehicle/ordnance report if vo_type not in ("vehicles","ordnance"): abort( 404 ) return render_template( "vo-report.html", + THEATER = theater, NATIONALITY = nat, VO_TYPE = vo_type, VO_TYPE0 = vo_type[:-1] if vo_type.endswith("s") else vo_type, YEAR = year, - MONTH = month + MONTH = month, )