@@ -678,3 +678,134 @@ def test_cmip7_generate_filename_numeric_time_branch(cmip7_vocab_instance):
678678
679679 assert "202001" in filename
680680 assert "202002" in filename
681+
682+
683+ def _make_cmip6_vocab (
684+ mock_vocab_data , mock_table_data , modeling_realm , source_components
685+ ):
686+ vocab_data = dict (mock_vocab_data )
687+ vocab_data ["source_id" ] = {
688+ "ACCESS-ESM1.6" : {
689+ ** vocab_data ["source_id" ]["ACCESS-ESM1.6" ],
690+ "model_component" : source_components ,
691+ }
692+ }
693+ table_data = {
694+ "Header" : mock_table_data ["Header" ],
695+ "variable_entry" : {
696+ "tas" : {
697+ ** mock_table_data ["variable_entry" ]["tas" ],
698+ "modeling_realm" : modeling_realm ,
699+ }
700+ },
701+ }
702+ with (
703+ patch .object (
704+ CMIP6Vocabulary , "_load_controlled_vocab" , return_value = vocab_data
705+ ),
706+ patch .object (CMIP6Vocabulary , "_load_table" , return_value = table_data ),
707+ ):
708+ return CMIP6Vocabulary (
709+ compound_name = "Amon.tas" ,
710+ experiment_id = "piControl" ,
711+ source_id = "ACCESS-ESM1.6" ,
712+ variant_label = "r1i1p1f1" ,
713+ grid_label = "gn" ,
714+ )
715+
716+
717+ @pytest .mark .unit
718+ def test_get_nominal_resolution_single_realm (mock_vocab_data , mock_table_data ):
719+ """Single realm: returns native_nominal_resolution without needing target_realm."""
720+ vocab = _make_cmip6_vocab (
721+ mock_vocab_data ,
722+ mock_table_data ,
723+ modeling_realm = "atmos" ,
724+ source_components = {"atmos" : {"native_nominal_resolution" : "100 km" }},
725+ )
726+ assert vocab ._get_nominal_resolution () == "100 km"
727+
728+
729+ @pytest .mark .unit
730+ def test_get_nominal_resolution_single_realm_missing_key (
731+ mock_vocab_data , mock_table_data
732+ ):
733+ """Single realm with no native_nominal_resolution key returns None."""
734+ vocab = _make_cmip6_vocab (
735+ mock_vocab_data ,
736+ mock_table_data ,
737+ modeling_realm = "atmos" ,
738+ source_components = {"atmos" : {"description" : "no resolution here" }},
739+ )
740+ assert vocab ._get_nominal_resolution () is None
741+
742+
743+ @pytest .mark .unit
744+ def test_get_nominal_resolution_multiple_realms_no_target_raises (
745+ mock_vocab_data , mock_table_data
746+ ):
747+ """Multiple modeling realms without target_realm raises ValueError."""
748+ vocab = _make_cmip6_vocab (
749+ mock_vocab_data ,
750+ mock_table_data ,
751+ modeling_realm = "atmos ocean" ,
752+ source_components = {
753+ "atmos" : {"native_nominal_resolution" : "100 km" },
754+ "ocean" : {"native_nominal_resolution" : "50 km" },
755+ },
756+ )
757+ with pytest .raises (ValueError , match = "multiple modeling realms" ):
758+ vocab ._get_nominal_resolution ()
759+
760+
761+ @pytest .mark .unit
762+ def test_get_nominal_resolution_multiple_realms_invalid_target_raises (
763+ mock_vocab_data , mock_table_data
764+ ):
765+ """target_realm not in the variable's realms raises ValueError."""
766+ vocab = _make_cmip6_vocab (
767+ mock_vocab_data ,
768+ mock_table_data ,
769+ modeling_realm = "atmos ocean" ,
770+ source_components = {
771+ "atmos" : {"native_nominal_resolution" : "100 km" },
772+ "ocean" : {"native_nominal_resolution" : "50 km" },
773+ },
774+ )
775+ with pytest .raises (ValueError , match = "not found in variable's modeling realms" ):
776+ vocab ._get_nominal_resolution (target_realm = "land" )
777+
778+
779+ @pytest .mark .unit
780+ def test_get_nominal_resolution_multiple_realms_valid_target (
781+ mock_vocab_data , mock_table_data
782+ ):
783+ """With a valid target_realm, returns resolution for the specified realm."""
784+ vocab = _make_cmip6_vocab (
785+ mock_vocab_data ,
786+ mock_table_data ,
787+ modeling_realm = "atmos ocean" ,
788+ source_components = {
789+ "atmos" : {"native_nominal_resolution" : "100 km" },
790+ "ocean" : {"native_nominal_resolution" : "50 km" },
791+ },
792+ )
793+ assert vocab ._get_nominal_resolution (target_realm = "atmos" ) == "100 km"
794+ assert vocab ._get_nominal_resolution (target_realm = "ocean" ) == "50 km"
795+
796+
797+ @pytest .mark .unit
798+ def test_get_nominal_resolution_multiple_realms_target_missing_key (
799+ mock_vocab_data , mock_table_data
800+ ):
801+ """Valid target_realm but no native_nominal_resolution in that component returns None."""
802+ vocab = _make_cmip6_vocab (
803+ mock_vocab_data ,
804+ mock_table_data ,
805+ modeling_realm = "atmos ocean" ,
806+ source_components = {
807+ "atmos" : {"description" : "no resolution" },
808+ "ocean" : {"native_nominal_resolution" : "50 km" },
809+ },
810+ )
811+ assert vocab ._get_nominal_resolution (target_realm = "atmos" ) is None
0 commit comments