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

Issue:
📋 [TASK] - Improve Tests in No Ext for Final 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/features/plugins/no_ext_for_final.feature b/python/features/plugins/no_ext_for_final.feature
new file mode 100644
index 000000000..0ac197c67
--- /dev/null
+++ b/python/features/plugins/no_ext_for_final.feature
@@ -0,0 +1,11 @@
+Feature:  No Ext for Final Evaluation
+
+    Scenario:  Check the Shapes constraint spec
+        Given I have the "./features/shapes/shapes.aac" file
+        When I run the "check" command with arguments "./features/shapes/shapes.aac" and with no flags
+        Then I should receive a message that the command was successful
+
+    Scenario:  Check the Bad Shapes Extensions constraint spec
+        Given I have the "./features/shapes/bad_shapes_extension.aac" file
+        When I run the "check" command with arguments "./features/shapes/bad_shapes_extension.aac" and with no flags
+        Then I should receive a message that the command was not successful
diff --git a/python/features/shapes/bad_shapes_extension.aac b/python/features/shapes/bad_shapes_extension.aac
new file mode 100644
index 000000000..5caf07def
--- /dev/null
+++ b/python/features/shapes/bad_shapes_extension.aac
@@ -0,0 +1,26 @@
+schema:
+    name: Shape
+    package: aac.shapes
+    modifiers:
+        - final
+    fields:
+        - name: area
+          type: number
+        - name: perimeter
+          type: number
+---
+schema:
+    name: Triangle
+    package: aac.shapes
+    extends:
+        - name: Shape
+          package: aac.shapes
+    fields:
+        - name: side_one_length
+          type: number
+        - name: side_two_length
+          type: number
+        - name: side_three_length
+          type: number
+        - name: height
+          type: number
diff --git a/python/src/aac/__init__.py b/python/src/aac/__init__.py
index 6bf61b4a0..36c84566b 100644
--- a/python/src/aac/__init__.py
+++ b/python/src/aac/__init__.py
@@ -12,7 +12,7 @@
 import logging
 import os
 
-__version__ = "0.4.40"
+__version__ = "0.4.41"
 
 __log_file_name__ = os.path.join(os.path.dirname(__file__), "aac.log")
 


Test patch:
diff --git a/python/tests/test_aac/plugins/no_ext_for_final/test_no_ext_for_final.py b/python/tests/test_aac/plugins/no_ext_for_final/test_no_ext_for_final.py
index a236fff74..4155c68ba 100644
--- a/python/tests/test_aac/plugins/no_ext_for_final/test_no_ext_for_final.py
+++ b/python/tests/test_aac/plugins/no_ext_for_final/test_no_ext_for_final.py
@@ -1,24 +1,18 @@
 from unittest import TestCase
-from typing import Tuple
-from click.testing import CliRunner
-from aac.execute.command_line import cli, initialize_cli
-from aac.execute.aac_execution_result import ExecutionStatus
 from aac.context.language_context import LanguageContext
-
-
-from aac.plugins.no_ext_for_final.no_ext_for_final_impl import plugin_name
-
-
 from aac.plugins.no_ext_for_final.no_ext_for_final_impl import no_extension_for_final
 
 
 class TestNoExtForFinal(TestCase):
-    def test_no_extension_for_final(self):
+
+    #  Nominal (expected pass) test with a single valid Schema definition
+    def test_no_extension_for_final_nominal(self):
         context = LanguageContext()
         schema_definition = context.get_definitions_by_name("aac.lang.Schema")
         if len(schema_definition) != 1:
             self.fail("Expected to find one and only one Schema definition")
         schema_definition = schema_definition[0]
+
         definitions = context.parse_and_load(root_schema_with_good_ext)
         result = no_extension_for_final(definitions[0].instance, definitions[0], schema_definition.instance)
         self.assertTrue(result.is_success())
@@ -26,13 +20,45 @@ def test_no_extension_for_final(self):
         self.assertTrue(result.is_success())
         context.remove_definitions(definitions)
 
-        definitions = context.parse_and_load(root_schema_with_bad_ext)
+
+    #  Off-nominal (expected fail) tests
+    def test_no_extension_for_final_offnominal(self):
+        context = LanguageContext()
+        schema_definition = context.get_definitions_by_name("aac.lang.Schema")
+        if len(schema_definition) != 1:
+            self.fail("Expected to find one and only one Schema definition")
+        schema_definition = schema_definition[0]
+
+
+        #  Off-nominal (expected fail) test with a circular schema definition
+        #  TestSchema tries to extend TestSchema
+        definitions = context.parse_and_load(root_schema_with_bad_ext_circular)
         result = no_extension_for_final(definitions[0].instance, definitions[0], schema_definition.instance)
         self.assertTrue(result.is_success())
         result = no_extension_for_final(definitions[1].instance, definitions[1], schema_definition.instance)
         self.assertFalse(result.is_success())
         context.remove_definitions(definitions)
 
+
+        #  Off-nominal (expected fail) test with a invalid schema definition
+        #  TestSchema defined twice
+        definitions = context.parse_and_load(root_schema_with_bad_ext_duplicate)
+        result = no_extension_for_final(definitions[0].instance, definitions[0], schema_definition.instance)
+        self.assertTrue(result.is_success())
+        result = no_extension_for_final(definitions[1].instance, definitions[1], schema_definition.instance)
+        self.assertFalse(result.is_success())
+
+
+        #  Off-nominal (expected fail) test with a invalid schema definition
+        #  Specified parent to extend does not exist (TestDoesNotExist)
+        definitions = context.parse_and_load(root_schema_with_bad_ext_does_not_exist)
+        result = no_extension_for_final(definitions[0].instance, definitions[0], schema_definition.instance)
+        self.assertTrue(result.is_success())
+        result = no_extension_for_final(definitions[1].instance, definitions[1], schema_definition.instance)
+        self.assertFalse(result.is_success())
+        context.remove_definitions(definitions)
+
+
 root_schema_with_good_ext = """
 schema:
   name: TestParent
@@ -46,7 +72,7 @@ def test_no_extension_for_final(self):
 schema:
   name: TestChild
   package: test_aac.plugins.no_ext_for_final
-  extends: 
+  extends:
     - name: TestParent
       package: test_aac.plugins.no_ext_for_final
   fields:
@@ -56,9 +82,9 @@ def test_no_extension_for_final(self):
       type: string
 """
 
-root_schema_with_bad_ext = """
+root_schema_with_bad_ext_circular = """
 schema:
-  name: TestSchema
+  name: TestParent
   package: test_aac.plugins.no_ext_for_final
   modifiers:
     - final
@@ -71,12 +97,60 @@ def test_no_extension_for_final(self):
 schema:
   name: TestChild
   package: test_aac.plugins.no_ext_for_final
-  extends: 
-    - name: TestSchema
+  extends:
+    - name: TestParent
       package: test_aac.plugins.no_ext_for_final
   fields:
     - name: name
       type: string
     - name: test_field
       type: string
-"""
\ No newline at end of file
+"""
+
+root_schema_with_bad_ext_duplicate = """
+schema:
+  name: TestParent
+  package: test_aac.plugins.no_ext_for_final
+  modifiers:
+    - final
+  fields:
+    - name: name
+      type: string
+    - name: test_field
+      type: string
+---
+schema:
+  name: TestParent
+  package: test_aac.plugins.no_ext_for_final
+  extends:
+    - name: TestChild
+      package: test_aac.plugins.no_ext_for_final
+  fields:
+    - name: name
+      type: string
+    - name: test_field
+      type: string
+"""
+
+root_schema_with_bad_ext_does_not_exist = """
+schema:
+  name: TestParent
+  package: test_aac.plugins.no_ext_for_final
+  fields:
+    - name: name
+      type: string
+    - name: test_field
+      type: string
+---
+schema:
+  name: TestChild
+  package: test_aac.plugins.no_ext_for_final
+  extends:
+    - name: TestDoesNotExist
+      package: test_aac.plugins.no_ext_for_final
+  fields:
+    - name: name
+      type: string
+    - name: test_field
+      type: string
+"""