def test_context_missing_fields(self): """ Case that a template's fields(keys) that are not part of the metadata's required fields are have no value in the context. """ # template with fields not in required fields or context field_name = "field_2" self.keys[field_name] = StringKey(field_name) self.keys["sppk"] = StringKey("sppk") template = tank.template.TemplatePath("{%s}{sppk}" % field_name, self.keys, self.project_root) # tank instance with this template self.tk.templates = {self.template_name: template} expected_msg = "Context %s can not determine value for fields %s needed by template %s" % ( self.context, ["sppk"], template) self.check_error_message(TankError, expected_msg, validate_settings, self.app_name, self.tk, self.context, self.metadata, self.config)
def test_key_alias(self): """ Test that key's aliased name is used in template.keys dict. """ key = StringKey("alias_name") self.keys["not_alias_name"] = key definition = "something/{not_alias_name}" template = Template(definition, self.keys) template_key = template.keys["alias_name"] self.assertEquals(key, template_key) self.assertEquals("something/{alias_name}", template.definition)
def test_aliased_key(self): key = StringKey("aliased_name") self.keys["initial_name"] = key definition = "something/{Shot}/{initial_name}" template = Template(definition, self.keys) fields = {"aliased_name": "some value", "Shot": "shot value"} result = template.missing_keys(fields) self.assertEquals([], result) fields = {"initial_name": "some_value", "Shot": "shot value"} result = template.missing_keys(fields) self.assertEquals(["aliased_name"], result)
def setUp(self): super(TestPathsFromTemplateGlob, self).setUp() keys = { "Shot": StringKey("Shot"), "version": IntegerKey("version", format_spec="03"), "seq_num": SequenceKey("seq_num", format_spec="05") } self.template = TemplatePath("{Shot}/{version}/filename.{seq_num}", keys, root_path=self.project_root)
def setUp(self): super(TestValidateContext, self).setUp() self.setup_fixtures() self.app_name = "test_app" self.template_name = "template_name" self.config_name = "template_config_name" self.config = {self.config_name: self.template_name} # set up test data with single sequence and shot seq = {"type": "Sequence", "name": "seq_name", "id": 3} seq_path = os.path.join(self.project_root, "sequence/Seq") self.add_production_path(seq_path, seq) shot = { "type": "Shot", "name": "shot_name", "id": 2, "project": self.project } shot_path = os.path.join(seq_path, "shot_code") self.add_production_path(shot_path, shot) # a second shot path without sequence shot_path_2 = os.path.join(self.project_root, "shot_code") self.add_production_path(shot_path_2, shot) # setup context with values for project and shot self.tk = tank.Tank(self.project_root) self.context = self.tk.context_from_path(shot_path) # Template to metadata self.metadata = { self.config_name: { "type": "template", "required_fields": [] } } # keys for templates self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot") }
def test_skip_invalid(self): """Test that files not valid for an template are not returned. This refers to bug reported in Ticket #17090 """ keys = { "Shot": StringKey("Shot"), "Sequence": StringKey("Sequence"), "Step": StringKey("Step"), "name": StringKey("name"), "version": IntegerKey("version", format_spec="03"), } definition = "sequences/{Sequence}/{Shot}/{Step}/work/{name}.v{version}.nk" template = TemplatePath(definition, keys, self.project_root, "my_template") self.tk._templates = {template.name: template} bad_file_path = os.path.join( self.project_root, "sequences", "Sequence1", "Shot1", "Foot", "work", "name1.va.nk", ) good_file_path = os.path.join( self.project_root, "sequences", "Sequence1", "Shot1", "Foot", "work", "name.v001.nk", ) self.create_file(bad_file_path) self.create_file(good_file_path) ctx_fields = {"Sequence": "Sequence1", "Shot": "Shot1", "Step": "Foot"} result = self.tk.paths_from_template(template, ctx_fields) self.assertIn(good_file_path, result) self.assertNotIn(bad_file_path, result)
def setUp(self): super(TestAsTemplateFields, self).setUp() # create a context obj using predefined data kws = {} kws["tk"] = self.tk kws["project"] = self.project kws["entity"] = self.shot kws["step"] = self.step self.ctx = context.Context(**kws) # create a template with which to filter self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot"), "Step": StringKey("Step"), "static_key": StringKey("static_key") } template_def = "/sequence/{Sequence}/{Shot}/{Step}/work" self.template = TemplatePath(template_def, self.keys, self.project_root)
def test_template_query_none(self): """ Case that shogun returns None as value. """ # set field value to None self.shot["sg_sequence"] = None query_key = StringKey("shot_seq", shotgun_entity_type="Shot", shotgun_field_name="sg_sequence") self.keys["shot_seq"] = query_key template_def = "/sequence/{Sequence}/{Shot}/{Step}/work/{shot_seq}.ext" template = TemplatePath(template_def, self.keys, self.project_root) fields = self.ctx.as_template_fields(template) self.assertEquals(fields['shot_seq'], None)
def setUp(self): super(TestValidateSettings, self).setUp() # set up data so as to supply a valid context seq = {"type": "Sequence", "name": "seq_name", "id": 3} seq_path = os.path.join(self.project_root, "sequence/Seq") self.add_production_path(seq_path, seq) shot = {"type": "Shot", "name": "shot_name", "id": 2, "project": self.project} shot_path = os.path.join(seq_path, "shot_code") self.add_production_path(shot_path, shot) # a second shot path without sequence shot_path_2 = os.path.join(self.project_root, "shot_code") self.add_production_path(shot_path_2, shot) # setup context with values for project and shot self.context = self.tk.context_from_path(shot_path) # The validation code needs a name for error reporting self.app_name = "test_app" # keys for templates self.keys = {"Sequence": StringKey("Sequence"), "Shot": StringKey("Shot")}
def test_subset_format(self): """ Test subset_format parameter """ if sys.version_info < (2, 6): # subset format not supported in py25 self.assertRaises(TankError, StringKey, "field_name", subset="(.{3}).*", subset_format="{0} FOO") return # test properties template_field = StringKey("field_name", subset="(.)().*", subset_format="{0} FOO") self.assertEqual("{0} FOO", template_field.subset_format) # cannot specify subset_format without subset self.assertRaises(TankError, StringKey, "field_name", subset_format="{0} FOO") tests = [] # basic test tests.append( { "short": "\u3042foo ", "full": "foobar", "template": StringKey("field_name", subset="(.{3}).*", subset_format="\u3042{0} ") } ) # unicode tests.append( { "short": u'\u3042\u308a\u304c ', "full": u'\u3042\u308a\u304c\u3068', "template": StringKey("field_name", subset="(.{3}).*", subset_format="{0} ") } ) # multi token tests.append( { "short": 'S J', "full": 'John Smith', "template": StringKey("field_name", subset='([A-Z])[a-z]* ([A-Z])[a-z]*', subset_format="{1} {0}") } ) for test in tests: print(test) short = test["short"] full = test["full"] template_field = test["template"] self.assertEqual(short, template_field.value_from_str(short)) self.assertEqual(full, template_field.value_from_str(full)) self.assertEqual(short, template_field.str_from_value(full)) self.assertTrue(template_field.validate(full)) self.assertFalse(template_field.validate(short[0])) self.assertRaises(TankError, template_field.str_from_value, short[0])
def setUp(self): super(TestTemplate, self).setUp() # Make various types of keys(fields) self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot", default="s1", choices=["s1", "s2", "shot_1"]), "Step": StringKey("Step"), "branch": StringKey("branch", filter_by="alphanumeric"), "name": StringKey("name"), "version": IntegerKey("version", format_spec="03"), "snapshot": IntegerKey("snapshot", format_spec="03"), "ext": StringKey("ext"), "seq_num": SequenceKey("seq_num"), "frame": SequenceKey("frame", format_spec="04"), "day_month_year": TimestampKey("day_month_year", format_spec="%d_%m_%Y") } # Make a template self.definition = "shots/{Sequence}/{Shot}/{Step}/work/{Shot}.{branch}.v{version}.{snapshot}.{day_month_year}.ma" self.template = Template(self.definition, self.keys)
def setUp(self): super(TestTemplatePath, self).setUp() # Make various types of keys(fields) self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot", default="s1", choices=["s1", "s2", "shot_1"]), "Step": StringKey("Step"), "branch": StringKey("branch", filter_by="alphanumeric"), "name": StringKey("name"), "version": IntegerKey("version", format_spec="03"), "snapshot": IntegerKey("snapshot", format_spec="03"), "ext": StringKey("ext"), "seq_num": SequenceKey("seq_num"), "frame": SequenceKey("frame", format_spec="04") } # Make a template self.definition = "shots/{Sequence}/{Shot}/{Step}/work/{Shot}.{branch}.v{version}.{snapshot}.ma" self.template_path = TemplatePath(self.definition, self.keys, self.project_root) # make template with sequence key self.sequence = TemplatePath("/path/to/seq.{frame}.ext", self.keys, "", "frame")
def test_ambigous_alphanum_middle(self): """ Can't resolve if values are too ambiguous """ self.keys["favorites"] = StringKey("favorites") definition = "build/maya/{Asset}_{name_alpha}_{favorites}.ext" input_path = "build/maya/cat_man_doogle_fever.ext" template = TemplatePath(definition, self.keys, "") expected_msg = ( "Template %s: Ambiguous values found for key 'Asset' could be any of: 'cat', 'cat_man'" % template) self.check_error_message(TankError, expected_msg, template.get_fields, input_path)
class TestEyeKey(TankTestBase): """ Tests that key representing eye can be setup. """ def setUp(self): super(TestEyeKey, self).setUp() self.eye_key = StringKey("eye", default="%V", choices=["%V", "L", "R"]) self.default_value = "%V" def test_validate(self): self.assertTrue(self.eye_key.validate(self.default_value)) self.assertTrue(self.eye_key.validate("L")) self.assertTrue(self.eye_key.validate("R")) def test_str_from_value_default(self): self.assertEquals(self.default_value, self.eye_key.str_from_value()) def test_set_choices(self): eye_key = StringKey("eye", default="%V", choices=["l", "r", "%V"]) self.assertTrue(self.eye_key.validate(self.default_value)) self.assertTrue(self.eye_key.validate("l")) self.assertTrue(self.eye_key.validate("r"))
def setUp(self): super(TestTemplatePath, self).setUp( parameters={"primary_root_name": "primary_with_a_different_name"}) # Make various types of keys(fields) self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot", default="s1", choices=["s1", "s2", "shot_1"]), "Step": StringKey("Step"), "branch": StringKey("branch", filter_by="alphanumeric"), "name": StringKey("name"), "name_alpha": StringKey("name_alpha", filter_by="alphanumeric"), "version": IntegerKey("version", format_spec="03"), "snapshot": IntegerKey("snapshot", format_spec="03"), "ext": StringKey("ext"), "seq_num": SequenceKey("seq_num"), "frame": SequenceKey("frame", format_spec="04") } # Make a template self.definition = "shots/{Sequence}/{Shot}/{Step}/work/{Shot}.{branch}.v{version}.{snapshot}.ma" # legacy style template object which only knows about the currently running operating system self.template_path_current_os_only = TemplatePath( self.definition, self.keys, self.project_root) project_root = os.path.join(self.tank_temp, "project_code") self._project_roots = {self.primary_root_name: {}} # Create the roots.yml like structure. Double down on the key names so it can be used in all scenarios # where we require the roots. for os_name in [ "windows_path", "linux_path", "mac_path", "win32", "linux2", "darwin" ]: self._project_roots[self.primary_root_name][os_name] = project_root self._primary_project_root = project_root # new style template object which supports all recognized platforms # get all OS roots for primary storage all_roots = self._project_roots[self.primary_root_name] self.template_path = TemplatePath(self.definition, self.keys, self.project_root, per_platform_roots=all_roots) self.project_root_template = TemplatePath("/", self.keys, self.project_root, per_platform_roots=all_roots) # make template with sequence key self.sequence = TemplatePath("/path/to/seq.{frame}.ext", self.keys, "", "frame")
def test_entity_field_query(self): """ Test template query to field linking to an entity. """ query_key = StringKey("shot_seq", shotgun_entity_type="Shot", shotgun_field_name="sg_sequence") self.keys["shot_seq"] = query_key # shot_extra cannot be gotten from path cache template_def = "/sequence/{Sequence}/{Shot}/{Step}/work/{shot_seq}.ext" template = TemplatePath(template_def, self.keys, self.project_root) result = self.ctx.as_template_fields(template) self.assertEquals("seq_name", result["shot_seq"])
class TestEyeKey(TankTestBase): """ Tests that key representing eye can be setup. """ def setUp(self): super(TestEyeKey, self).setUp() self.eye_key = StringKey("eye", default="%V", choices=["%V","L","R"]) self.default_value = "%V" def test_validate(self): self.assertTrue(self.eye_key.validate(self.default_value)) self.assertTrue(self.eye_key.validate("L")) self.assertTrue(self.eye_key.validate("R")) def test_str_from_value_default(self): self.assertEquals(self.default_value, self.eye_key.str_from_value()) def test_set_choices(self): eye_key = StringKey("eye", default="%V", choices=["l","r", "%V"]) self.assertTrue(self.eye_key.validate(self.default_value)) self.assertTrue(self.eye_key.validate("l")) self.assertTrue(self.eye_key.validate("r"))
def test_multi_ambiguous(self): """ Can't resolve if values are too ambiguous """ self.keys["favorites"] = StringKey("favorites") definition = "build/{Asset}_{name}_{favorites}/maya" input_path = "build/cat_man_doogle_do_dandy_dod/maya" template = TemplatePath(definition, self.keys, "") expected_msg = ( "Template %s: Ambiguous values found for key 'Asset' could be any of: " "'cat', 'cat_man', 'cat_man_doogle', 'cat_man_doogle_do'" % template) self.check_error_message(TankError, expected_msg, template.get_fields, input_path)
def test_optional_fields_not_in_template(self): """ Case that optional fields are specified, but not available in the template. """ field_name = "optional_field" self.keys[field_name] = StringKey(field_name) schema = {self.config_name:{"type":"template", "required_fields":[], "optional_fields": [field_name]}} # Template without the optional field template = tank.template.TemplatePath("{Shot}", self.keys, self.project_root) # tank instance with this template self.tk.templates={self.template_name:template} # If no error, then success validate_settings(self.app_name, self.tk, self.context, schema, self.config)
def test_default_values_detected(self): """ Case that field's value cannot be determined by the context, but field has a default value. """ # template with field with default value field_name = "field_1" self.keys[field_name] = StringKey(field_name, default="default") template = tank.template.TemplatePath("{%s}" % field_name, self.keys, self.project_root) # tank instance with this template self.tk.templates={self.template_name:template} # If no error, then success validate_settings(self.app_name, self.tk, self.context, self.metadata, self.config)
def test_good_alphanumeric(self): """ Tests applying valid values for alphanumeric key. """ key = StringKey("alpha_num", filter_by="alphanumeric") template = TemplatePath("{alpha_num}", {"alpha_num": key}, self.project_root) valid_values = [ "allChars", "123454", "mixed09", "29mixed", "mi2344xEd", "CAPS" ] for valid_value in valid_values: result = template.apply_fields({"alpha_num": valid_value}) expected = os.path.join(self.project_root, valid_value) self.assertEquals(expected, result)
def setUp(self): super(TestStringKey, self).setUp() self.str_field = StringKey("field_name") self.alphanum_field = StringKey("field_name", filter_by="alphanumeric") self.alpha_field = StringKey("field_name", filter_by="alpha") self.regex_field = StringKey("field_name", filter_by="^[0-9]{3}@[a-z]+") # e.g 123@foo self.choice_field = StringKey("field_name", choices=["a", "b"]) self.default_field = StringKey("field_name", default="b")
def test_subset(self): """ Test subset_format parameter """ # test properties template_field = StringKey("field_name", subset="(.{3}).*") self.assertEqual("(.{3}).*", template_field.subset) # test bad regex self.assertRaises(TankError, StringKey, "field_name", subset="({4}.).*BROKENREGEX") # test basic regex template_field = StringKey("field_name", subset="(.{3}).*") tests = [] # basic test tests.append({"short": "foo", "full": "foobar", "template": StringKey("field_name", subset="(.{3}).*")}) tests.append({"short": u"foo", "full": u"foobar", "template": StringKey("field_name", subset="(.{3}).*")}) # unicode tests.append({ "short": u'\u3042\u308a\u304c', "full": u'\u3042\u308a\u304c\u3068', "template": StringKey("field_name", subset="(.{3}).*")} ) # multi token tests.append({ "short": 'JS', "full": 'John Smith', "template": StringKey("field_name", subset='([A-Z])[a-z]* ([A-Z])[a-z]*')} ) for test in tests: short = test["short"] full = test["full"] template_field = test["template"] self.assertEqual(short, template_field.value_from_str(short)) self.assertEqual(full, template_field.value_from_str(full)) self.assertEqual(short, template_field.str_from_value(full)) self.assertTrue(template_field.validate(full)) self.assertFalse(template_field.validate(short[0])) self.assertRaises(TankError, template_field.str_from_value, short[0])
def test_required_fields(self): """ Fields listed as required do not need to be specified in the context. """ # template with fields not in required fields or context field_name = "field_1" self.keys[field_name] = StringKey(field_name) template = tank.template.TemplatePath("{%s}" % field_name, self.keys, self.project_root) # tank instance with this template self.tk.templates={self.template_name:template} # add field to required list in meta data self.metadata[self.config_name]["required_fields"] = [field_name] # If no error, then success validate_settings(self.app_name, self.tk, self.context, self.metadata, self.config)
def test_bad_alphanumeric(self): """ Tests applying non-alphanumeric values to keys of type alphanumeric. """ # single key template key = StringKey("alpha_num", filter_by="alphanumeric") template = TemplatePath("{alpha_num}", {"alpha_num": key}, self.project_root) invalid_values = [ "_underscore", "white space", "@mpersand", "par(enthes)", "###" ] for invalid_value in invalid_values: expected_msg = "%s Illegal value '%s' does not fit filter" % ( str(key), invalid_value) self.check_error_message(TankError, expected_msg, template.apply_fields, {"alpha_num": invalid_value})
def setUp(self): super(TestTemplatePath, self).setUp() # Make various types of keys(fields) self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot", default="s1", choices=["s1", "s2", "shot_1"]), "Step": StringKey("Step"), "branch": StringKey("branch", filter_by="alphanumeric"), "name": StringKey("name"), "name_alpha": StringKey("name_alpha", filter_by="alphanumeric"), "version": IntegerKey("version", format_spec="03"), "snapshot": IntegerKey("snapshot", format_spec="03"), "ext": StringKey("ext"), "seq_num": SequenceKey("seq_num"), "frame": SequenceKey("frame", format_spec="04") } # Make a template self.definition = "shots/{Sequence}/{Shot}/{Step}/work/{Shot}.{branch}.v{version}.{snapshot}.ma" # legacy style template object which only knows about the currently running operating system self.template_path_current_os_only = TemplatePath( self.definition, self.keys, self.project_root) # new style template object which supports all recognized platforms # get all OS roots for primary storage all_roots = self.pipeline_configuration.get_all_platform_data_roots( )["primary"] self.template_path = TemplatePath(self.definition, self.keys, self.project_root, per_platform_roots=all_roots) self.project_root_template = TemplatePath("/", self.keys, self.project_root, per_platform_roots=all_roots) # make template with sequence key self.sequence = TemplatePath("/path/to/seq.{frame}.ext", self.keys, "", "frame")
def test_query_cached(self): """ Test that if same key query is run more than once, the value is cached. """ query_key = StringKey("shot_extra", shotgun_entity_type="Shot", shotgun_field_name="extra_field") self.keys["shot_extra"] = query_key # shot_extra cannot be gotten from path cache template_def = "/sequence/{Sequence}/{Shot}/{Step}/work/{shot_extra}.ext" template = TemplatePath(template_def, self.keys, self.project_root) result = self.ctx.as_template_fields(template) self.assertEquals("extravalue", result["shot_extra"]) # clear mock history so we can check it. finds = self.tk.shotgun.finds # do same query again result = self.ctx.as_template_fields(template) self.assertEquals("extravalue", result["shot_extra"]) # Check that the shotgun method find_one was not used self.assertEqual(finds, self.tk.shotgun.finds)
def test_choices(self): choices_value = ["a", "b"] template_field = StringKey("field_name", choices=choices_value) self.assertEquals(choices_value, template_field.choices)
def setUp(self): super(TestStringKey, self).setUp() self.str_field = StringKey("field_name") self.alpha_field = StringKey("field_name", filter_by="alphanumeric") self.choice_field = StringKey("field_name", choices=["a", "b"]) self.default_field = StringKey("field_name", default="b")
class TestStringKey(ShotgunTestBase): def setUp(self): super(TestStringKey, self).setUp() self.str_field = StringKey("field_name") self.alphanum_field = StringKey("field_name", filter_by="alphanumeric") self.alpha_field = StringKey("field_name", filter_by="alpha") self.regex_field = StringKey("field_name", filter_by="^[0-9]{3}@[a-z]+") # e.g 123@foo self.choice_field = StringKey("field_name", choices=["a", "b"]) self.default_field = StringKey("field_name", default="b") def test_invalid(self): self.assertRaises(TankError, StringKey, "S!hot") def test_default(self): default_value = "default_value" template_field = StringKey("field_name", default=default_value) self.assertEqual(default_value, template_field.default) def test_no_default(self): template_field = StringKey("field_name") self.assertIsNone(template_field.default) def test_choices(self): choices_value = ["a", "b"] template_field = StringKey("field_name", choices=choices_value) self.assertEqual(choices_value, template_field.choices) def test_exclusions(self): exclusions = ["a", "b"] template_field = StringKey("field_name", exclusions=exclusions) self.assertEqual(exclusions, template_field.exclusions) self.assertFalse(template_field.validate("a")) self.assertFalse(template_field.validate("b")) def test_illegal_choice_alphanumic(self): choices_value = ["@", "b"] self.assertRaises(TankError, StringKey, "field_name", choices=choices_value, filter_by="alphanumeric") def test_default_choices_mismatch(self): """Case that default value is not part of enumerated choices.""" default_value = "c" choices_value = ["a", "b"] self.assertRaises(TankError, StringKey, "field_name", choices=choices_value, default=default_value) def test_choices_exclusions_conflict(self): """Case that same value is put as valid and invalid choice.""" choices = ["a", "b"] exclusions = ["c", "a"] self.assertRaises(TankError, StringKey, "field_name", choices=choices, exclusions=exclusions) def test_name_set(self): name = "field_name" template_field = StringKey("field_name") self.assertEqual(name, template_field.name) def test_validate_string_good(self): value = "some string" self.assertTrue(self.str_field.validate(value)) def test_validate_alphanum_good(self): value = "some0alphanumeric0string" self.assertTrue(self.alphanum_field.validate(value)) def test_validate_alphanum_bad(self): bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: self.assertFalse(self.alphanum_field.validate(bad_value)) def test_validate_regex_good(self): value = "123@foobar" self.assertTrue(self.regex_field.validate(value)) def test_validate_regex_bad(self): bad_values = ["basd", "1234@asd", " 123@foo", "a-b", "*"] for bad_value in bad_values: self.assertFalse(self.regex_field.validate(bad_value)) def test_validate_alpha_good(self): value = "somealphastring" self.assertTrue(self.alpha_field.validate(value)) def test_validate_alpha_bad(self): bad_values = ["a2b", "a_b", "a b", "a-b", "*"] for bad_value in bad_values: self.assertFalse(self.alpha_field.validate(bad_value)) def test_str_from_value_good(self): value = "a string" expected = value result = self.str_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_empty(self): value = "" expected = value result = self.str_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_good_choice(self): value = "b" expected = value result = self.choice_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_bad_choice(self): value = "c" expected = "%s Illegal value: 'c' not in choices: ['a', 'b']" % str(self.choice_field) self.check_error_message(TankError, expected, self.choice_field.str_from_value, value) def test_str_from_value_use_default(self): expected = "b" result = self.default_field.str_from_value() self.assertEqual(expected, result) def test_str_from_value_no_default(self): expected = "No value provided and no default available for %s" % self.str_field self.check_error_message(TankError, expected, self.str_field.str_from_value) def test_str_from_value_alphanum_good(self): value = "a9b9C" expected = value result = self.alphanum_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_alphanum_empty(self): value = "" expected = value result = self.alphanum_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_alphanum_bad(self): base_expected = "%s Illegal value '%%s' does not fit filter_by 'alphanumeric'" % self.alphanum_field bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = base_expected % bad_value self.check_error_message(TankError, expected, self.alphanum_field.str_from_value, bad_value) def test_str_from_value_ignore_type_alphanum(self): bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = bad_value result = self.alphanum_field.str_from_value(bad_value, ignore_type=True) self.assertEqual(expected, result) def test_str_from_value_alpha_good(self): value = "abC" expected = value result = self.alpha_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_alpha_empty(self): value = "" expected = value result = self.alpha_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_alpha_bad(self): base_expected = "%s Illegal value '%%s' does not fit filter_by 'alpha'" % self.alpha_field bad_values = ["a2b", "a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = base_expected % bad_value self.check_error_message(TankError, expected, self.alpha_field.str_from_value, bad_value) def test_str_from_value_ignore_type_alpha(self): bad_values = ["a2b", "a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = bad_value result = self.regex_field.str_from_value(bad_value, ignore_type=True) self.assertEqual(expected, result) def test_str_from_value_regex_good(self): value = "444@jlasdlkjasd" expected = value result = self.regex_field.str_from_value(value) self.assertEqual(expected, result) def test_str_from_value_regex_bad(self): base_expected = "%s Illegal value '%%s' does not fit filter_by '^[0-9]{3}@[a-z]+'" % self.regex_field bad_values = ["", " 121@fff", "asdasd", "123@", "*"] for bad_value in bad_values: expected = base_expected % bad_value self.check_error_message(TankError, expected, self.regex_field.str_from_value, bad_value) def test_str_from_value_ignore_type_regex(self): bad_values = ["", " 121@fff", "asdasd", "123@", "*"] for bad_value in bad_values: expected = bad_value result = self.regex_field.str_from_value(bad_value, ignore_type=True) self.assertEqual(expected, result) def test_value_from_str(self): str_value = "something" self.assertEqual(str_value, self.str_field.value_from_str(str_value)) def test_shotgun_entity_type_set(self): str_field = StringKey("field_name", shotgun_entity_type="Shot") self.assertEqual("Shot", str_field.shotgun_entity_type) def test_shotgun_field_name_without_entity_type(self): """ Test that setting shotgun_field name is not possible if not setting shotgun_entity_type. """ self.assertRaises(TankError, StringKey, "field_name", shotgun_field_name="code") def test_shotgun_field_name_set(self): str_field = StringKey("field_name", shotgun_entity_type="Shot", shotgun_field_name="code") self.assertEqual("Shot", str_field.shotgun_entity_type) self.assertEqual("code", str_field.shotgun_field_name) def test_repr(self): expected = "<Sgtk StringKey field_name>" self.assertEqual(expected, str(self.str_field)) def test_subset(self): """ Test subset_format parameter """ # test properties template_field = StringKey("field_name", subset="(.{3}).*") self.assertEqual("(.{3}).*", template_field.subset) # test bad regex self.assertRaises(TankError, StringKey, "field_name", subset="({4}.).*BROKENREGEX") # test basic regex template_field = StringKey("field_name", subset="(.{3}).*") tests = [] # basic test tests.append({"short": "foo", "full": "foobar", "template": StringKey("field_name", subset="(.{3}).*")}) tests.append({"short": u"foo", "full": u"foobar", "template": StringKey("field_name", subset="(.{3}).*")}) # unicode tests.append({ "short": u'\u3042\u308a\u304c', "full": u'\u3042\u308a\u304c\u3068', "template": StringKey("field_name", subset="(.{3}).*")} ) # multi token tests.append({ "short": 'JS', "full": 'John Smith', "template": StringKey("field_name", subset='([A-Z])[a-z]* ([A-Z])[a-z]*')} ) for test in tests: short = test["short"] full = test["full"] template_field = test["template"] self.assertEqual(short, template_field.value_from_str(short)) self.assertEqual(full, template_field.value_from_str(full)) self.assertEqual(short, template_field.str_from_value(full)) self.assertTrue(template_field.validate(full)) self.assertFalse(template_field.validate(short[0])) self.assertRaises(TankError, template_field.str_from_value, short[0]) def test_subset_format(self): """ Test subset_format parameter """ if sys.version_info < (2, 6): # subset format not supported in py25 self.assertRaises(TankError, StringKey, "field_name", subset="(.{3}).*", subset_format="{0} FOO") return # test properties template_field = StringKey("field_name", subset="(.)().*", subset_format="{0} FOO") self.assertEqual("{0} FOO", template_field.subset_format) # cannot specify subset_format without subset self.assertRaises(TankError, StringKey, "field_name", subset_format="{0} FOO") tests = [] # basic test tests.append( { "short": "\u3042foo ", "full": "foobar", "template": StringKey("field_name", subset="(.{3}).*", subset_format="\u3042{0} ") } ) # unicode tests.append( { "short": u'\u3042\u308a\u304c ', "full": u'\u3042\u308a\u304c\u3068', "template": StringKey("field_name", subset="(.{3}).*", subset_format="{0} ") } ) # multi token tests.append( { "short": 'S J', "full": 'John Smith', "template": StringKey("field_name", subset='([A-Z])[a-z]* ([A-Z])[a-z]*', subset_format="{1} {0}") } ) for test in tests: print(test) short = test["short"] full = test["full"] template_field = test["template"] self.assertEqual(short, template_field.value_from_str(short)) self.assertEqual(full, template_field.value_from_str(full)) self.assertEqual(short, template_field.str_from_value(full)) self.assertTrue(template_field.validate(full)) self.assertFalse(template_field.validate(short[0])) self.assertRaises(TankError, template_field.str_from_value, short[0])
def test_name_set(self): name = "field_name" template_field = StringKey("field_name") self.assertEquals(name, template_field.name)
def test_set_choices(self): eye_key = StringKey("eye", default="%V", choices=["l", "r", "%V"]) self.assertTrue(self.eye_key.validate(self.default_value)) self.assertTrue(self.eye_key.validate("l")) self.assertTrue(self.eye_key.validate("r"))
def setUp(self): super(TestEyeKey, self).setUp() self.eye_key = StringKey("eye", default="%V", choices=["%V", "L", "R"]) self.default_value = "%V"
def test_exclusions(self): exclusions = ["a", "b"] template_field = StringKey("field_name", exclusions=exclusions) self.assertEquals(exclusions, template_field.exclusions) self.assertFalse(template_field.validate("a")) self.assertFalse(template_field.validate("b"))
class TestStringKey(TankTestBase): def setUp(self): super(TestStringKey, self).setUp() self.str_field = StringKey("field_name") self.alpha_field = StringKey("field_name", filter_by="alphanumeric") self.choice_field = StringKey("field_name", choices=["a", "b"]) self.default_field = StringKey("field_name", default="b") def test_default(self): default_value = "default_value" template_field = StringKey("field_name", default=default_value) self.assertEquals(default_value, template_field.default) def test_no_default(self): template_field = StringKey("field_name") self.assertIsNone(template_field.default) def test_choices(self): choices_value = ["a", "b"] template_field = StringKey("field_name", choices=choices_value) self.assertEquals(choices_value, template_field.choices) def test_exclusions(self): exclusions = ["a", "b"] template_field = StringKey("field_name", exclusions=exclusions) self.assertEquals(exclusions, template_field.exclusions) self.assertFalse(template_field.validate("a")) self.assertFalse(template_field.validate("b")) def test_illegal_choice_alphanumic(self): choices_value = ["@", "b"] self.assertRaises(TankError, StringKey, "field_name", choices=choices_value, filter_by="alphanumeric") def test_default_choices_mismatch(self): """Case that default value is not part of enumerated choices.""" default_value = "c" choices_value = ["a", "b"] self.assertRaises(TankError, StringKey, "field_name", choices=choices_value, default=default_value) def test_choices_exclusions_conflict(self): """Case that same value is put as valid and invalid choice.""" choices = ["a", "b"] exclusions = ["c", "a"] self.assertRaises(TankError, StringKey, "field_name", choices=choices, exclusions=exclusions) def test_name_set(self): name = "field_name" template_field = StringKey("field_name") self.assertEquals(name, template_field.name) def test_validate_string_good(self): value = "some string" self.assertTrue(self.str_field.validate(value)) def test_validate_alphanum_good(self): value = "some0alphanumeric0string" self.assertTrue(self.alpha_field.validate(value)) def test_validate_alphanum_bad(self): bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: self.assertFalse(self.alpha_field.validate(bad_value)) def test_str_from_value_good(self): value = "a string" expected = value result = self.str_field.str_from_value(value) self.assertEquals(expected, result) def test_str_from_value_empty(self): value = "" expected = value result = self.str_field.str_from_value(value) self.assertEquals(expected, result) def test_str_from_value_good_choice(self): value = "b" expected = value result = self.choice_field.str_from_value(value) self.assertEquals(expected, result) def test_str_from_value_bad_choice(self): value = "c" expected = "%s Illegal value: 'c' not in choices: ['a', 'b']" % str(self.choice_field) self.check_error_message(TankError, expected, self.choice_field.str_from_value, value) def test_str_from_value_use_default(self): expected = "b" result = self.default_field.str_from_value() self.assertEquals(expected, result) def test_str_from_value_no_default(self): expected = "No value provided and no default available for %s" % self.str_field self.check_error_message(TankError, expected, self.str_field.str_from_value) def test_str_from_value_alphanum_good(self): value = "a9b9C" expected = value result = self.alpha_field.str_from_value(value) self.assertEquals(expected, result) def test_str_from_value_alphanum_empty(self): value = "" expected = value result = self.alpha_field.str_from_value(value) self.assertEquals(expected, result) def test_str_from_value_alphanum_bad(self): base_expected = "%s Illegal value '%%s' does not fit filter" % self.alpha_field bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = base_expected % bad_value self.check_error_message(TankError, expected, self.alpha_field.str_from_value, bad_value) def test_str_from_value_ignore_type_alphanum(self): bad_values = ["a_b", "a b", "a-b", "*"] for bad_value in bad_values: expected = bad_value result = self.alpha_field.str_from_value(bad_value, ignore_type=True) self.assertEquals(expected, result) def test_value_from_str(self): str_value = "something" self.assertEquals(str_value, self.str_field.value_from_str(str_value)) def test_shotgun_entity_type_set(self): str_field = StringKey("field_name", shotgun_entity_type="Shot") self.assertEquals("Shot", str_field.shotgun_entity_type) def test_shotgun_field_name_without_entity_type(self): """ Test that setting shotgun_field name is not possible if not setting shotgun_entity_type. """ self.assertRaises(TankError, StringKey, "field_name", shotgun_field_name="code") def test_shotgun_field_name_set(self): str_field = StringKey("field_name", shotgun_entity_type="Shot", shotgun_field_name="code") self.assertEquals("Shot", str_field.shotgun_entity_type) self.assertEquals("code", str_field.shotgun_field_name) def test_repr(self): expected = "<Sgtk StringKey field_name>" self.assertEquals(expected, str(self.str_field))
def setUp(self): super(TestGetKeysSepInValue, self).setUp() key = StringKey("Asset") self.keys["Asset"] = key
def setUp(self): super(TestAbstractPathsFromTemplate, self).setUp() self.setup_fixtures() keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot"), "eye": StringKey("eye", default="%V", choices=["left", "right", "%V"], abstract=True), "name": StringKey("name"), "SEQ": SequenceKey("SEQ", format_spec="04"), } definition = "sequences/{Sequence}/{Shot}/{eye}/{name}.{SEQ}.exr" self.template = TemplatePath(definition, keys, self.project_root) # create fixtures seq_path = os.path.join(self.project_root, "sequences", "SEQ_001") self.shot_a_path = os.path.join(seq_path, "AAA") self.shot_b_path = os.path.join(seq_path, "BBB") eye_left_a = os.path.join(self.shot_a_path, "left") self.create_file(os.path.join(eye_left_a, "filename.0001.exr")) self.create_file(os.path.join(eye_left_a, "filename.0002.exr")) self.create_file(os.path.join(eye_left_a, "filename.0003.exr")) self.create_file(os.path.join(eye_left_a, "filename.0004.exr")) self.create_file(os.path.join(eye_left_a, "anothername.0001.exr")) self.create_file(os.path.join(eye_left_a, "anothername.0002.exr")) self.create_file(os.path.join(eye_left_a, "anothername.0003.exr")) self.create_file(os.path.join(eye_left_a, "anothername.0004.exr")) eye_left_b = os.path.join(self.shot_b_path, "left") self.create_file(os.path.join(eye_left_b, "filename.0001.exr")) self.create_file(os.path.join(eye_left_b, "filename.0002.exr")) self.create_file(os.path.join(eye_left_b, "filename.0003.exr")) self.create_file(os.path.join(eye_left_b, "filename.0004.exr")) self.create_file(os.path.join(eye_left_b, "anothername.0001.exr")) self.create_file(os.path.join(eye_left_b, "anothername.0002.exr")) self.create_file(os.path.join(eye_left_b, "anothername.0003.exr")) self.create_file(os.path.join(eye_left_b, "anothername.0004.exr")) eye_right_a = os.path.join(self.shot_a_path, "right") self.create_file(os.path.join(eye_right_a, "filename.0001.exr")) self.create_file(os.path.join(eye_right_a, "filename.0002.exr")) self.create_file(os.path.join(eye_right_a, "filename.0003.exr")) self.create_file(os.path.join(eye_right_a, "filename.0004.exr")) self.create_file(os.path.join(eye_right_a, "anothername.0001.exr")) self.create_file(os.path.join(eye_right_a, "anothername.0002.exr")) self.create_file(os.path.join(eye_right_a, "anothername.0003.exr")) self.create_file(os.path.join(eye_right_a, "anothername.0004.exr")) eye_right_b = os.path.join(self.shot_b_path, "right") self.create_file(os.path.join(eye_right_b, "filename.0001.exr")) self.create_file(os.path.join(eye_right_b, "filename.0002.exr")) self.create_file(os.path.join(eye_right_b, "filename.0003.exr")) self.create_file(os.path.join(eye_right_b, "filename.0004.exr")) self.create_file(os.path.join(eye_right_b, "anothername.0001.exr")) self.create_file(os.path.join(eye_right_b, "anothername.0002.exr")) self.create_file(os.path.join(eye_right_b, "anothername.0003.exr")) self.create_file(os.path.join(eye_right_b, "anothername.0004.exr"))
def setUp(self): super(TestEyeKey, self).setUp() self.eye_key = StringKey("eye", default="%V", choices=["%V","L","R"]) self.default_value = "%V"