Repository: DevOps-MBSE/AaC (language: python)

Issue:
📋 [TASK] - Improve Tests in Context Unit Tests
### Parent Feature

#844

### Task Description

As an AaC Test Developer, I want to expand the test coverage in my unit tests, so that I can have more confidence in the robustness of my code.

### Acceptance Criteria

- [ ] Update test logic as necessary to expand test coverage. 
  - [ ] Happy path and sad path at a minimum
- [ ] (Stretch) Incorporate a behave feature file for testing if applicable.
- [ ] Run `flake8` on the targeted test directory and address findings.
- [ ] Document any identified gaps.

### Unresolved questions

_No response_


Discussion / hints:

Fix patch:
diff --git a/python/src/aac/__init__.py b/python/src/aac/__init__.py
index c0e146fa3..1744449ea 100644
--- a/python/src/aac/__init__.py
+++ b/python/src/aac/__init__.py
@@ -12,7 +12,7 @@
 import logging
 import os
 
-__version__ = "0.4.34"
+__version__ = "0.4.35"
 
 __log_file_name__ = os.path.join(os.path.dirname(__file__), "aac.log")
 


Test patch:
diff --git a/python/tests/test_aac/context/test_definition.py b/python/tests/test_aac/context/test_definition.py
index c81eedf94..cf9aa3230 100644
--- a/python/tests/test_aac/context/test_definition.py
+++ b/python/tests/test_aac/context/test_definition.py
@@ -1,5 +1,6 @@
 from unittest import TestCase
 
+from aac.context.definition import Definition
 from aac.context.language_context import LanguageContext
 
 
@@ -18,10 +19,88 @@ def test_get_root_key(self):
 
         definition = context.get_definitions_by_name("abstract")
         self.assertEqual(definition[0].get_root_key(), "modifier")
-        
+
+    def test_is_import(self):
+        context = LanguageContext()
+        definition = context.parse_and_load(IMPORT_DEFINITION)[0]
+        self.assertTrue(definition.is_import())
+        definition = context.get_definitions_by_name("Schema")[0]
+        self.assertFalse(definition.is_import())
+
+    def test_get_python_module_name(self):
+        context = LanguageContext()
+        definition = context.get_definitions_by_name("Schema")[0]
+        module_name = definition.get_python_module_name()
+        self.assertEqual(module_name, "aac.lang")
+
+    def test_get_python_class_name(self):
+        context = LanguageContext()
+        definition = context.parse_and_load(DEFINITION_VALID)[0]
+        class_name = definition.get_python_class_name()
+        self.assertEqual(class_name, "ModelName")
+
+    def test_get_fully_qualified_name(self):
+        context = LanguageContext()
+        definition = context.get_definitions_by_name("Schema")[0]
+        name = definition.get_fully_qualified_name()
+        self.assertEqual(name, "aac.lang.Schema")
+
     def test_to_yaml(self):
         context = LanguageContext()
         definition = context.get_definitions_by_name("Schema")
         yaml = definition[0].to_yaml()
         self.assertIn("schema:", yaml)
         self.assertIn("name: Schema", yaml)
+
+    def test_definition_fail_incorrect_types(self):
+        context = LanguageContext()
+        schema_definition = context.get_definitions_by_name("Schema")[0]
+        with self.assertRaises(TypeError):
+            # This is probably the worst way to make a definition, it should normally be handled by Language Context
+            definition = Definition(
+                name=123,
+                package=schema_definition.package,
+                content=schema_definition.content,
+                source=schema_definition.source,
+                structure=schema_definition.structure,
+            )
+        with self.assertRaises(TypeError):
+            definition = Definition(            # noqa: F841
+                name=schema_definition.name,
+                package=123,
+                content=schema_definition.content,
+                source=schema_definition.source,
+                structure=schema_definition.structure,
+            )
+        with self.assertRaises(TypeError):
+            definition = Definition(            # noqa: F841
+                name=schema_definition.name,
+                package=schema_definition.package,
+                content=123,
+                source=schema_definition.source,
+                structure=schema_definition.structure,
+            )
+
+    def test_get_python_module_name_default(self):
+        context = LanguageContext()
+        definition = context.parse_and_load(DEFINITION_VALID)[0]
+        module_name = definition.get_python_module_name()
+        self.assertEqual(module_name, "default")
+
+
+IMPORT_DEFINITION = """
+import:
+  files:
+    - ./structures.yaml
+    - ../alarm_clock/structures.yaml
+"""
+
+DEFINITION_VALID = """
+model:
+    name: Model Name
+"""
+
+DEFINITION_INVALID_ROOT_KEY = """
+notaroot:
+    name: notaroot
+"""
diff --git a/python/tests/test_aac/context/test_definition_parser.py b/python/tests/test_aac/context/test_definition_parser.py
index f33820bf4..028cb32e9 100644
--- a/python/tests/test_aac/context/test_definition_parser.py
+++ b/python/tests/test_aac/context/test_definition_parser.py
@@ -6,6 +6,17 @@
 
 
 class TestDefinitionParser(TestCase):
+    def test_find_definitions_by_name(self):
+        context = LanguageContext()
+        definitions = context.get_definitions_by_name("Schema")
+        self.assertEqual(len(definitions), 1)
+        self.assertEqual(definitions[0].name, "Schema")
+        self.assertIsNotNone(definitions[0].instance)
+
+        context.parse_and_load(VALID_AAC_YAML_CONTENT_SPACE_IN_NAME)
+        definitions = context.get_definitions_by_name("Test Schema2")
+        self.assertEqual(definitions[0].name, "Test Schema2")
+
     def test_load_definitions_pass(self):
         parser = DefinitionParser()
         context = LanguageContext()
@@ -24,11 +35,12 @@ def test_load_definitions_pass(self):
     def test_load_definitions_fail(self):
         parser = DefinitionParser()
         context = LanguageContext()
-        with self.assertRaises(ParserError) as e:
+        with self.assertRaises(ParserError):
             definitions = parse(INVALID_AAC_YAML_CONTENT)
-            loaded_definitions = parser.load_definitions(context=context, parsed_definitions=definitions)
+            loaded_definitions = parser.load_definitions(context=context, parsed_definitions=definitions)  # noqa: F841
             self.assertFalse(definitions[0].source.is_loaded_in_context)
 
+
 VALID_AAC_YAML_CONTENT = """
 schema:
   name: TestSchema
@@ -53,6 +65,31 @@ def test_load_definitions_fail(self):
         This is a test field.
 """.strip()
 
+VALID_AAC_YAML_CONTENT_SPACE_IN_NAME = """
+schema:
+  name: Test Schema2
+  description: |
+    This is a test schema.
+  fields:
+    - name: string_field
+      type: string
+      description: |
+        This is a test field.
+    - name: integer_field
+      type: integer
+      description: |
+        This is a test field.
+    - name: boolean_field
+      type: boolean
+      description: |
+        This is a test field.
+    - name: number_field
+      type: number
+      description: |
+        This is a test field.
+""".strip()
+
+
 INVALID_AAC_YAML_CONTENT = """
 schema:
   description: |
diff --git a/python/tests/test_aac/context/test_language_context.py b/python/tests/test_aac/context/test_language_context.py
index 67cd60f50..2ca0b53de 100644
--- a/python/tests/test_aac/context/test_language_context.py
+++ b/python/tests/test_aac/context/test_language_context.py
@@ -1,6 +1,8 @@
 from unittest import TestCase
 
 from aac.context.language_context import LanguageContext
+from aac.context.language_error import LanguageError
+from aac.in_out.parser._parser_error import ParserError
 
 
 class TestLanguageContext(TestCase):
@@ -19,6 +21,30 @@ def test_get_aac_core_as_yaml(self):
         for definition in context.get_aac_core_definitions():
             self.assertIn(f"name: {definition.name}", aac_yaml)
 
+    def test_get_aac_core_definitions(self):
+        context = LanguageContext()
+        definitions = context.get_aac_core_definitions()
+        self.assertIn("name: Schema", str(definitions))
+        self.assertIn("name: Requirement", str(definitions))
+        self.assertIn("name: Model", str(definitions))
+
+    def test_is_aac_instance(self):
+        context = LanguageContext()
+        object = context.create_aac_object("Schema", {})
+        self.assertTrue(context.is_aac_instance(object, "Schema"))
+
+    def test_create_aac_object(self):
+        context = LanguageContext()
+        object = context.create_aac_object("Schema", {})
+        self.assertEqual(str(type(object)), "<class 'aac.lang.Schema'>")
+
+    # Something is going wrong with this method, it is failing to create the class. Putting a pin in it.
+    # def test_create_aac_enum(self):
+    #     context = LanguageContext()
+    #     enum = context.create_aac_enum("RequirementVerificationMethod", "TEST")
+    #     self.assertEqual(str(type(enum)), "aac.lang.RequirementVerificationMethod")
+    #     self.assertEqual(str(enum), "TEST")
+
     def test_parse_and_load(self):
         context = LanguageContext()
         definitions = context.parse_and_load(VALID_AAC_YAML_CONTENT)
@@ -27,6 +53,16 @@ def test_parse_and_load(self):
         self.assertEqual(definitions[0].name, "TestSchema")
         self.assertEqual(len(definitions[0].instance.fields), 4)
 
+    def test_remove_definitions(self):
+        context = LanguageContext()
+        loaded_definition = context.parse_and_load(VALID_AAC_YAML_CONTENT)
+        name = loaded_definition[0].name
+        definition = context.get_definitions_by_name(name)
+        self.assertGreater(len(definition), 0)
+        context.remove_definitions(definition)
+        definition = context.get_definitions_by_name(name)
+        self.assertEqual(len(definition), 0)
+
     def test_get_definitions(self):
         context = LanguageContext()
         definitions = context.get_definitions()
@@ -107,6 +143,84 @@ def test_get_values_by_field_chain(self):
             values = context.get_values_by_field_chain(val)
             self.assertGreater(len(values), 1)
 
+    def test_is_aac_instance_fail(self):
+        with self.assertRaises(KeyError):
+            context = LanguageContext()
+            context.parse_and_load(VALID_AAC_YAML_CONTENT)
+            object = context.create_aac_object("TestSchema", {})
+            context.remove_definitions(context.get_definitions_by_name("TestSchema"))
+            context.is_aac_instance(object, "TestSchema")
+
+    def test_create_aac_object_incorrect_type(self):
+        with self.assertRaises(AttributeError):
+            context = LanguageContext()
+            object = context.create_aac_object("Schema", "Attribute")  # noqa: F841
+
+    # Something is going wrong with this method, it is failing to create the class. Putting a pin in it.
+    # def test_create_aac_enum_incorrect_type(self):
+    #   with self.assertRaises(AttributeError):
+    #       context = LanguageContext()
+    #       enum = context.create_aac_enum("RequirementVerificationMethod", 123)
+
+    def test_parse_and_load_non_definition(self):
+        with self.assertRaises(ParserError):
+            context = LanguageContext()
+            context.parse_and_load("definition")
+
+    def test_remove_definitions_fail(self):
+        with self.assertRaises(AttributeError):
+            context = LanguageContext()
+            context.remove_definitions("TestSchema")
+
+    def test_get_python_type_from_primitive_no_type(self):
+        context = LanguageContext()
+        with self.assertRaises(LanguageError):
+            context.get_python_type_from_primitive("type")
+
+    # Should this method return an error of some kind when it finds no definitions of a name?
+    def test_get_definitions_by_name_fail(self):
+        context = LanguageContext()
+        definitions = context.get_definitions_by_name("invalid name")
+        self.assertEqual(definitions, [])
+        with self.assertRaises(TypeError):
+            definitions = context.get_definitions_by_name(123)
+
+    # Should this method return an error of some kind when it finds no definitions of a root?
+    def test_get_definitions_by_root_fail(self):
+        context = LanguageContext()
+        definitions = context.get_definitions_by_root("invalid root")
+        self.assertEqual(definitions, [])
+        with self.assertRaises(TypeError):
+            definitions = context.get_definitions_by_name(123)
+
+    def test_get_defining_schema_for_root_fail(self):
+        with self.assertRaises(LanguageError):
+            context = LanguageContext()
+            definitions = context.get_defining_schema_for_root("Schema")
+
+    def test_get_python_type_from_primitive_fail(self):
+        with self.assertRaises(LanguageError):
+            context = LanguageContext()
+            context.get_python_type_from_primitive("schema")
+
+    def test_is_extension_of_fail(self):
+        context = LanguageContext()
+        definition = context.get_definitions_by_name("string")
+        self.assertFalse(context.is_extension_of(definition[0], "aac.lang", "AacType"))
+
+    def test_get_definitions_of_type_fail(self):
+        with self.assertRaises(LanguageError):
+            context = LanguageContext()
+            context.get_definitions_of_type("invalid_type", "invalid_name")
+
+    def test_get_values_by_field_chain(self):
+        context = LanguageContext()
+        test_values = ["schema.field.name", "enum.value", "primitives.python_type"]
+        for val in test_values:
+            values = context.get_values_by_field_chain(val)
+            self.assertLess(len(values), 1)
+
+
 VALID_AAC_YAML_CONTENT = """
 schema:
   name: TestSchema
diff --git a/python/tests/test_aac/context/test_lexeme.py b/python/tests/test_aac/context/test_lexeme.py
index ff3129155..de7976e35 100644
--- a/python/tests/test_aac/context/test_lexeme.py
+++ b/python/tests/test_aac/context/test_lexeme.py
@@ -15,5 +15,15 @@ def test_lexeme(self):
         self.assertEqual(lex_one, lex_two)
 
         string_value = str(lex_one)
-        self.assertTrue(isinstance(string_value, str))
-        self.assertTrue(len(string_value) > 0)
+        self.assertIsInstance(string_value, str)
+        self.assertGreater(len(string_value), 0)
+
+    def test_lexeme_fail(self):
+        loc = SourceLocation(1, 2, 3, 4)
+        src = "my_source.aac"
+        value = "my_value"
+
+        lex_one = Lexeme(loc, src, value)
+        lex_two = Lexeme(loc, value, src)
+
+        self.assertNotEqual(lex_one, lex_two)
diff --git a/python/tests/test_aac/context/test_no_undefined_fields.py b/python/tests/test_aac/context/test_no_undefined_fields.py
index b8e9df860..2eae57378 100644
--- a/python/tests/test_aac/context/test_no_undefined_fields.py
+++ b/python/tests/test_aac/context/test_no_undefined_fields.py
@@ -1,6 +1,7 @@
 from unittest import TestCase
 from aac.context.language_context import LanguageContext
 from aac.context.language_error import LanguageError
+from aac.in_out.parser._parser_error import ParserError
 
 
 class TestNoUndefinedFields(TestCase):
@@ -14,6 +15,12 @@ def test_no_extra_fields(self):
             definitions = context.parse_and_load(BAD_EXTRA_SUB_FIELDS)
             context.remove_definitions(definitions)
 
+    def test_no_undefined_fields(self):
+        context = LanguageContext()
+        with self.assertRaises(ParserError):
+            definitions = context.parse_and_load(EMPTY_FIELDS)
+
+
 
 # we've got plenty of good cases in the default language definition, so just test the bad case
 BAD_EXTRA_FIELDS = """
@@ -26,7 +33,7 @@ def test_no_extra_fields(self):
         - name: name
           type: string
           is_required: true
-        - name: extra   
+        - name: extra
           type: string
 """
 
@@ -40,6 +47,12 @@ def test_no_extra_fields(self):
           type: string
           is_required: true
           not_defined_in_field: fail
-        - name: extra   
+        - name: extra
           type: string
 """
+
+EMPTY_FIELDS = """
+schema:
+    name:
+    package:
+"""
diff --git a/python/tests/test_aac/context/test_source_location.py b/python/tests/test_aac/context/test_source_location.py
index 486cab5b4..b4a48274f 100644
--- a/python/tests/test_aac/context/test_source_location.py
+++ b/python/tests/test_aac/context/test_source_location.py
@@ -1,9 +1,62 @@
 from unittest import TestCase
 from aac.context.source_location import SourceLocation
+from aac.context.language_context import LanguageContext
 
 
 class TestSourceLocation(TestCase):
     def test_source_location(self):
         loc = SourceLocation(1, 2, 3, 4)
-        
-        self.assertTrue(isinstance(loc.to_tuple(), tuple))
+        self.assertIsInstance(loc.to_tuple(), tuple)
+
+        loc2 = SourceLocation(2, 1, 3, 4)
+        self.assertIsInstance(loc2.to_tuple(), tuple)
+
+        loc3 = SourceLocation(1, 2, 4, 3)
+        self.assertIsInstance(loc3.to_tuple(), tuple)
+        self.assertNotEqual(loc, loc2, loc3)
+
+    def test_source_location_mapping(self):
+        context = LanguageContext()
+        definition = context.parse_and_load(VALID_AAC_YAML_CONTENT)[0]
+        lexemes = definition.lexemes
+
+        self.assertEqual(lexemes[0].value, "schema")
+        self.assertEqual(lexemes[0].location.line, 0)
+        self.assertEqual(lexemes[0].location.column, 0)
+        self.assertEqual(lexemes[0].location.position, 0)
+        self.assertEqual(lexemes[0].location.span, 6)
+
+        self.assertEqual(lexemes[1].value, "name")
+        self.assertEqual(lexemes[1].location.line, 1)
+        self.assertEqual(lexemes[1].location.column, 2)
+        self.assertEqual(lexemes[1].location.position, 10)
+        self.assertEqual(lexemes[1].location.span, 4)
+
+    def test_source_location_incorrect_type(self):
+        with self.assertRaises(TypeError):
+            loc = SourceLocation("1", "2", "3", "4")  # noqa: F841
+
+
+VALID_AAC_YAML_CONTENT = """
+schema:
+  name: TestSchema
+  description: |
+    This is a test schema.
+  fields:
+    - name: string_field
+      type: string
+      description: |
+        This is a test field.
+    - name: integer_field
+      type: integer
+      description: |
+        This is a test field.
+    - name: boolean_field
+      type: boolean
+      description: |
+        This is a test field.
+    - name: number_field
+      type: number
+      description: |
+        This is a test field.
+""".strip()