def test_object_caching(self): # Creating a Feature with the same name as an existing # Feature must return the existing Feature, if both are # associated with the same BinaryFeaturesModel. feature1 = BaseFeature(self.bfm, 'voiced') feature2 = BaseFeature(self.bfm, 'voiced') self.assertEqual(feature1, feature2) feature3 = BaseFeature(self.bfm, 'consonantal') self.assertNotEqual(feature1, feature3) bfm2 = BinaryFeaturesModel() feature4 = BaseFeature(bfm2, 'voiced') self.assertNotEqual(feature1, feature4) # It is an error to create a Feature with the same IPA form # but of a different type (subclass). self.assertRaises(InvalidFeatureError, SuprasegmentalFeature, self.bfm, 'voiced') # Initialisation of a Feature should happen only once. character1 = BaseCharacter(self.bfm, 'a') character1.set_feature_value(feature1, HAS_FEATURE) self.assertEqual(feature1.get_value_characters(HAS_FEATURE), set([character1])) feature5 = BaseFeature(self.bfm, 'voiced') self.assertEqual(feature1.get_value_characters(HAS_FEATURE), set([character1])) feature6 = SuprasegmentalFeature(self.bfm, 'syllabic') character2 = SuprasegmentalCharacter(self.bfm, 'b') character2.set_feature_value(feature6, HAS_FEATURE) self.assertEqual(feature6.get_value_characters(HAS_FEATURE), set([character2])) feature7 = SuprasegmentalFeature(self.bfm, 'syllabic') self.assertEqual(feature6.get_value_characters(HAS_FEATURE), set([character2]))
def test_object_caching (self): # Creating a Feature with the same name as an existing # Feature must return the existing Feature, if both are # associated with the same BinaryFeaturesModel. feature1 = BaseFeature(self.bfm, 'voiced') feature2 = BaseFeature(self.bfm, 'voiced') self.assertEqual(feature1, feature2) feature3 = BaseFeature(self.bfm, 'consonantal') self.assertNotEqual(feature1, feature3) bfm2 = BinaryFeaturesModel() feature4 = BaseFeature(bfm2, 'voiced') self.assertNotEqual(feature1, feature4) # It is an error to create a Feature with the same IPA form # but of a different type (subclass). self.assertRaises(InvalidFeatureError, SuprasegmentalFeature, self.bfm, 'voiced') # Initialisation of a Feature should happen only once. character1 = BaseCharacter(self.bfm, 'a') character1.set_feature_value(feature1, HAS_FEATURE) self.assertEqual(feature1.get_value_characters(HAS_FEATURE), set([character1])) feature5 = BaseFeature(self.bfm, 'voiced') self.assertEqual(feature1.get_value_characters(HAS_FEATURE), set([character1])) feature6 = SuprasegmentalFeature(self.bfm, 'syllabic') character2 = SuprasegmentalCharacter(self.bfm, 'b') character2.set_feature_value(feature6, HAS_FEATURE) self.assertEqual(feature6.get_value_characters(HAS_FEATURE), set([character2])) feature7 = SuprasegmentalFeature(self.bfm, 'syllabic') self.assertEqual(feature6.get_value_characters(HAS_FEATURE), set([character2]))
def test_feature_value(self): character = SuprasegmentalCharacter(self.bfm, 'a') feature = SuprasegmentalFeature(self.bfm, 'voiced') character.set_feature_value(feature, HAS_FEATURE) value = character.get_feature_value(feature) self.assertEqual(value, HAS_FEATURE) character.set_feature_value(feature, NOT_HAS_FEATURE) value = character.get_feature_value(feature) self.assertEqual(value, NOT_HAS_FEATURE)
def test_feature_value (self): character = SuprasegmentalCharacter(self.bfm, 'a') feature = SuprasegmentalFeature(self.bfm, 'voiced') character.set_feature_value(feature, HAS_FEATURE) value = character.get_feature_value(feature) self.assertEqual(value, HAS_FEATURE) character.set_feature_value(feature, NOT_HAS_FEATURE) value = character.get_feature_value(feature) self.assertEqual(value, NOT_HAS_FEATURE)
def test_delete(self): Feature._cache = {} self.assertEqual(len(Feature._cache), 0) feature = SuprasegmentalFeature(self.bfm, 'voiced') character = SuprasegmentalCharacter(self.bfm, 'a') character.set_feature_value(feature, HAS_FEATURE) self.assertEqual(len(Feature._cache), 1) self.assertEqual(character.get_feature_value(feature), HAS_FEATURE) feature.delete() self.assertEqual(len(Feature._cache), 0) self.assertRaises(MismatchedModelsError, character.get_feature_value, feature)
def test_delete (self): Feature._cache = {} self.assertEqual(len(Feature._cache), 0) feature = SuprasegmentalFeature(self.bfm, 'voiced') character = SuprasegmentalCharacter(self.bfm, 'a') character.set_feature_value(feature, HAS_FEATURE) self.assertEqual(len(Feature._cache), 1) self.assertEqual(character.get_feature_value(feature), HAS_FEATURE) feature.delete() self.assertEqual(len(Feature._cache), 0) self.assertRaises(MismatchedModelsError, character.get_feature_value, feature)
def test_normalised_form_cluster_creation (self): # Test that the correct subclass of Cluster is created from a # normalised form. bfm = BinaryFeaturesModel() feature1 = BaseFeature(bfm, 'anterior') feature2 = SuprasegmentalFeature(bfm, 'long') character1 = BaseCharacter(bfm, 'a') character1.set_feature_value(feature1, HAS_FEATURE) character2 = SuprasegmentalCharacter(bfm, 'b') character2.set_feature_value(feature2, HAS_FEATURE) nf1 = NormalisedForm('{}{}'.format(BNFM, HAS_FEATURE)) nf2 = NormalisedForm('{}{}'.format(SNFM, HAS_FEATURE)) cluster1 = Cluster(bfm, normalised_form=nf1) cluster2 = Cluster(bfm, normalised_form=nf2) self.assertTrue(isinstance(cluster1, BaseCluster)) self.assertTrue(isinstance(cluster2, SuprasegmentalCluster)) self.assertRaises(IllegalArgumentError, Cluster, '')
def test_normalised_form_cluster_creation(self): # Test that the correct subclass of Cluster is created from a # normalised form. bfm = BinaryFeaturesModel() feature1 = BaseFeature(bfm, 'anterior') feature2 = SuprasegmentalFeature(bfm, 'long') character1 = BaseCharacter(bfm, 'a') character1.set_feature_value(feature1, HAS_FEATURE) character2 = SuprasegmentalCharacter(bfm, 'b') character2.set_feature_value(feature2, HAS_FEATURE) nf1 = NormalisedForm('{}{}'.format(BNFM, HAS_FEATURE)) nf2 = NormalisedForm('{}{}'.format(SNFM, HAS_FEATURE)) cluster1 = Cluster(bfm, normalised_form=nf1) cluster2 = Cluster(bfm, normalised_form=nf2) self.assertTrue(isinstance(cluster1, BaseCluster)) self.assertTrue(isinstance(cluster2, SuprasegmentalCluster)) self.assertRaises(IllegalArgumentError, Cluster, '')
def test_normalised_form(self): feature1 = SuprasegmentalFeature(self.bfm, 'anterior') character = SuprasegmentalCharacter(self.bfm, 'n') character.set_feature_value(feature1, HAS_FEATURE) self.assertEqual(character.normalised_form, NormalisedForm('{0}{1}'.format(SNFM, HAS_FEATURE))) # Adding a feature changes the normalised form. feature2 = SuprasegmentalFeature(self.bfm, 'dental') # All features must have a value. self.assertRaises(InvalidCharacterError, getattr, character, 'normalised_form') character.set_feature_value(feature2, NOT_HAS_FEATURE) self.assertEqual( character.normalised_form, NormalisedForm('{0}{1}{2}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # The order of the normalised form feature values is # alphabetical by feature name. feature3 = SuprasegmentalFeature(self.bfm, 'consonantal') character.set_feature_value(feature3, HAS_FEATURE) self.assertEqual( character.normalised_form, NormalisedForm('{0}{1}{1}{2}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # Renaming a feature may change the normalised form. feature3.name = 'vocalic' self.assertEqual( character.normalised_form, NormalisedForm('{0}{1}{2}{1}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # Changing a feature value changes the normalised form. character.set_feature_value(feature1, INAPPLICABLE_FEATURE) self.assertEqual( character.normalised_form, NormalisedForm('{0}{3}{2}{1}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE))) # Removing a feature value changes the normalised form. feature3.delete() self.assertEqual( character.normalised_form, NormalisedForm('{0}{2}{1}'.format(SNFM, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE))) # Adding a feature of a different type does not change the # normalised form. feature4 = BaseFeature(self.bfm, 'syllabic') self.assertEqual( character.normalised_form, NormalisedForm('{0}{2}{1}'.format(SNFM, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE)))
def test_object_caching (self): # Creating a Character with the same IPA form as an existing # Character must return the existing Character, if both are # associated with the same BinaryFeaturesModel. character1 = BaseCharacter(self.bfm, 'a') character2 = BaseCharacter(self.bfm, 'a') self.assertEqual(character1, character2) character3 = BaseCharacter(self.bfm, 'b') self.assertNotEqual(character1, character3) bfm2 = BinaryFeaturesModel() character4 = BaseCharacter(bfm2, 'a') self.assertNotEqual(character1, character4) # It is an error to create a Character with the same IPA form # but of a different type (subclass). self.assertRaises(InvalidCharacterError, DiacriticCharacter, self.bfm, 'a') # Initialising of the Character should happen only once. feature = BaseFeature(self.bfm, 'voiced') character1.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character1.get_feature_value(feature), HAS_FEATURE) character5 = BaseCharacter(self.bfm, 'a') self.assertEqual(character1.get_feature_value(feature), HAS_FEATURE) character6 = DiacriticCharacter(self.bfm, 'c') character6.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character6.get_feature_value(feature), HAS_FEATURE) character7 = DiacriticCharacter(self.bfm, 'c') self.assertEqual(character6.get_feature_value(feature), HAS_FEATURE) character8 = SpacingCharacter(self.bfm, 'd') character8.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character8.get_feature_value(feature), HAS_FEATURE) character9 = SpacingCharacter(self.bfm, 'd') self.assertEqual(character8.get_feature_value(feature), HAS_FEATURE) character10 = SuprasegmentalCharacter(self.bfm, 'e') feature2 = SuprasegmentalFeature(self.bfm, 'syllabic') character10.set_feature_value(feature2, HAS_FEATURE) self.assertEqual(character10.get_feature_value(feature2), HAS_FEATURE) character11 = SuprasegmentalCharacter(self.bfm, 'e') self.assertEqual(character10.get_feature_value(feature2), HAS_FEATURE)
def test_object_caching(self): # Creating a Character with the same IPA form as an existing # Character must return the existing Character, if both are # associated with the same BinaryFeaturesModel. character1 = BaseCharacter(self.bfm, 'a') character2 = BaseCharacter(self.bfm, 'a') self.assertEqual(character1, character2) character3 = BaseCharacter(self.bfm, 'b') self.assertNotEqual(character1, character3) bfm2 = BinaryFeaturesModel() character4 = BaseCharacter(bfm2, 'a') self.assertNotEqual(character1, character4) # It is an error to create a Character with the same IPA form # but of a different type (subclass). self.assertRaises(InvalidCharacterError, DiacriticCharacter, self.bfm, 'a') # Initialising of the Character should happen only once. feature = BaseFeature(self.bfm, 'voiced') character1.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character1.get_feature_value(feature), HAS_FEATURE) character5 = BaseCharacter(self.bfm, 'a') self.assertEqual(character1.get_feature_value(feature), HAS_FEATURE) character6 = DiacriticCharacter(self.bfm, 'c') character6.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character6.get_feature_value(feature), HAS_FEATURE) character7 = DiacriticCharacter(self.bfm, 'c') self.assertEqual(character6.get_feature_value(feature), HAS_FEATURE) character8 = SpacingCharacter(self.bfm, 'd') character8.set_feature_value(feature, HAS_FEATURE) self.assertEqual(character8.get_feature_value(feature), HAS_FEATURE) character9 = SpacingCharacter(self.bfm, 'd') self.assertEqual(character8.get_feature_value(feature), HAS_FEATURE) character10 = SuprasegmentalCharacter(self.bfm, 'e') feature2 = SuprasegmentalFeature(self.bfm, 'syllabic') character10.set_feature_value(feature2, HAS_FEATURE) self.assertEqual(character10.get_feature_value(feature2), HAS_FEATURE) character11 = SuprasegmentalCharacter(self.bfm, 'e') self.assertEqual(character10.get_feature_value(feature2), HAS_FEATURE)
def test_normalised_form (self): feature1 = SuprasegmentalFeature(self.bfm, 'anterior') character = SuprasegmentalCharacter(self.bfm, 'n') character.set_feature_value(feature1, HAS_FEATURE) self.assertEqual(character.normalised_form, NormalisedForm( '{0}{1}'.format(SNFM, HAS_FEATURE))) # Adding a feature changes the normalised form. feature2 = SuprasegmentalFeature(self.bfm, 'dental') # All features must have a value. self.assertRaises(InvalidCharacterError, getattr, character, 'normalised_form') character.set_feature_value(feature2, NOT_HAS_FEATURE) self.assertEqual(character.normalised_form, NormalisedForm( '{0}{1}{2}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # The order of the normalised form feature values is # alphabetical by feature name. feature3 = SuprasegmentalFeature(self.bfm, 'consonantal') character.set_feature_value(feature3, HAS_FEATURE) self.assertEqual(character.normalised_form, NormalisedForm( '{0}{1}{1}{2}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # Renaming a feature may change the normalised form. feature3.name = 'vocalic' self.assertEqual(character.normalised_form, NormalisedForm( '{0}{1}{2}{1}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE))) # Changing a feature value changes the normalised form. character.set_feature_value(feature1, INAPPLICABLE_FEATURE) self.assertEqual(character.normalised_form, NormalisedForm( '{0}{3}{2}{1}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE))) # Removing a feature value changes the normalised form. feature3.delete() self.assertEqual(character.normalised_form, NormalisedForm( '{0}{2}{1}'.format(SNFM, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE))) # Adding a feature of a different type does not change the # normalised form. feature4 = BaseFeature(self.bfm, 'syllabic') self.assertEqual(character.normalised_form, NormalisedForm( '{0}{2}{1}'.format(SNFM, NOT_HAS_FEATURE, INAPPLICABLE_FEATURE)))
def test_value_characters(self): feature = SuprasegmentalFeature(self.bfm, 'voiced') self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set()) character = SuprasegmentalCharacter(self.bfm, 'a') character.set_feature_value(feature, HAS_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set([character])) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set()) character.set_feature_value(feature, NOT_HAS_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set([character])) character.set_feature_value(feature, INAPPLICABLE_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set())
def test_value_characters (self): feature = SuprasegmentalFeature(self.bfm, 'voiced') self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set()) character = SuprasegmentalCharacter(self.bfm, 'a') character.set_feature_value(feature, HAS_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set([character])) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set()) character.set_feature_value(feature, NOT_HAS_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set([character])) character.set_feature_value(feature, INAPPLICABLE_FEATURE) self.assertEqual(feature.get_value_characters(HAS_FEATURE), set()) self.assertEqual(feature.get_value_characters(NOT_HAS_FEATURE), set())
class ClusterTestCase(unittest.TestCase): def setUp(self): self.bfm = BinaryFeaturesModel() self.phrase = SuprasegmentalFeature(self.bfm, 'phrase') self.stressed = SuprasegmentalFeature(self.bfm, 'stressed') self.syllabic = SuprasegmentalFeature(self.bfm, 'syllabic') self.a = SuprasegmentalCharacter(self.bfm, 'a') self.a.set_feature_value(self.phrase, HAS_FEATURE) self.a.set_feature_value(self.stressed, INAPPLICABLE_FEATURE) self.a.set_feature_value(self.syllabic, NOT_HAS_FEATURE) self.b = SuprasegmentalCharacter(self.bfm, 'b') self.b.set_feature_value(self.phrase, INAPPLICABLE_FEATURE) self.b.set_feature_value(self.stressed, NOT_HAS_FEATURE) self.b.set_feature_value(self.syllabic, INAPPLICABLE_FEATURE) def test_applier_form(self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters=[self.a]) af1 = '{0}{1}{2}{3}{4}'.format(AFM, SNFM, HAS_FEATURE, INAPPLICABLE_FEATURE, NOT_HAS_FEATURE) self.assertEqual(cluster1.applier_form, af1) cluster2 = SuprasegmentalCluster( self.bfm, suprasegmental_characters=[self.a, self.b]) af2 = '{0}{1}{2}{3}{3}'.format(AFM, SNFM, HAS_FEATURE, NOT_HAS_FEATURE) self.assertEqual(cluster2.applier_form, af2) def test_normalised_form(self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters=[self.a]) nf1 = NormalisedForm('{0}{1}{2}{3}'.format(SNFM, HAS_FEATURE, INAPPLICABLE_FEATURE, NOT_HAS_FEATURE)) self.assertEqual(cluster1.normalised_form, nf1) cluster2 = SuprasegmentalCluster( self.bfm, suprasegmental_characters=[self.a, self.b]) nf2 = NormalisedForm('{0}{1}{2}{2}'.format(SNFM, HAS_FEATURE, NOT_HAS_FEATURE)) self.assertEqual(cluster2.normalised_form, nf2) cluster3 = Cluster(self.bfm, normalised_form=nf2) self.assertEqual(cluster3.normalised_form, nf2) def test_string_form(self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters=[self.a]) self.assertEqual(str(cluster1), 'a') cluster2 = SuprasegmentalCluster( self.bfm, suprasegmental_characters=[self.a, self.b]) self.assertEqual(str(cluster2), 'ab') cluster3 = SuprasegmentalCluster( self.bfm, suprasegmental_characters=[self.b, self.a]) self.assertEqual(str(cluster3), 'ba') def test_suprasegmental_cluster_creation_illegal(self): bfm1 = BinaryFeaturesModel() bfm2 = BinaryFeaturesModel() character1 = BaseCharacter(bfm1, 'a') character3 = SuprasegmentalCharacter(bfm1, 'b') character4 = SuprasegmentalCharacter(bfm2, 'c') nf1 = NormalisedForm('{}{}'.format(SNFM, HAS_FEATURE)) # A SuprasegmentalCluster must be initialised with at least # one suprasegmental character or a normalised form. self.assertRaises(IllegalArgumentError, SuprasegmentalCluster, bfm1) # A SuprasegmentalCluster must not be initialised with both # suprasegmental characters and a normalised form. self.assertRaises(IllegalArgumentError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character3], normalised_form=nf1) # All of the characters in a cluster must be associated with # the same binary features model. self.assertRaises(MismatchedModelsError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character4]) # All of the characters in a cluster must be suprasegmental. self.assertRaises(MismatchedTypesError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character1, character3])
class ClusterTestCase (unittest.TestCase): def setUp (self): self.bfm = BinaryFeaturesModel() self.phrase = SuprasegmentalFeature(self.bfm, 'phrase') self.stressed = SuprasegmentalFeature(self.bfm, 'stressed') self.syllabic = SuprasegmentalFeature(self.bfm, 'syllabic') self.a = SuprasegmentalCharacter(self.bfm, 'a') self.a.set_feature_value(self.phrase, HAS_FEATURE) self.a.set_feature_value(self.stressed, INAPPLICABLE_FEATURE) self.a.set_feature_value(self.syllabic, NOT_HAS_FEATURE) self.b = SuprasegmentalCharacter(self.bfm, 'b') self.b.set_feature_value(self.phrase, INAPPLICABLE_FEATURE) self.b.set_feature_value(self.stressed, NOT_HAS_FEATURE) self.b.set_feature_value(self.syllabic, INAPPLICABLE_FEATURE) def test_applier_form (self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a]) af1 = '{0}{1}{2}{3}{4}'.format(AFM, SNFM, HAS_FEATURE, INAPPLICABLE_FEATURE, NOT_HAS_FEATURE) self.assertEqual(cluster1.applier_form, af1) cluster2 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a, self.b]) af2 = '{0}{1}{2}{3}{3}'.format(AFM, SNFM, HAS_FEATURE, NOT_HAS_FEATURE) self.assertEqual(cluster2.applier_form, af2) def test_normalised_form (self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a]) nf1 = NormalisedForm('{0}{1}{2}{3}'.format( SNFM, HAS_FEATURE, INAPPLICABLE_FEATURE, NOT_HAS_FEATURE)) self.assertEqual(cluster1.normalised_form, nf1) cluster2 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a, self.b]) nf2 = NormalisedForm('{0}{1}{2}{2}'.format( SNFM, HAS_FEATURE, NOT_HAS_FEATURE)) self.assertEqual(cluster2.normalised_form, nf2) cluster3 = Cluster(self.bfm, normalised_form=nf2) self.assertEqual(cluster3.normalised_form, nf2) def test_string_form (self): cluster1 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a]) self.assertEqual(str(cluster1), 'a') cluster2 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.a, self.b]) self.assertEqual(str(cluster2), 'ab') cluster3 = SuprasegmentalCluster(self.bfm, suprasegmental_characters= [self.b, self.a]) self.assertEqual(str(cluster3), 'ba') def test_suprasegmental_cluster_creation_illegal (self): bfm1 = BinaryFeaturesModel() bfm2 = BinaryFeaturesModel() character1 = BaseCharacter(bfm1, 'a') character3 = SuprasegmentalCharacter(bfm1, 'b') character4 = SuprasegmentalCharacter(bfm2, 'c') nf1 = NormalisedForm('{}{}'.format(SNFM, HAS_FEATURE)) # A SuprasegmentalCluster must be initialised with at least # one suprasegmental character or a normalised form. self.assertRaises(IllegalArgumentError, SuprasegmentalCluster, bfm1) # A SuprasegmentalCluster must not be initialised with both # suprasegmental characters and a normalised form. self.assertRaises(IllegalArgumentError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character3], normalised_form=nf1) # All of the characters in a cluster must be associated with # the same binary features model. self.assertRaises(MismatchedModelsError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character4]) # All of the characters in a cluster must be suprasegmental. self.assertRaises(MismatchedTypesError, SuprasegmentalCluster, bfm1, suprasegmental_characters=[character1, character3])