# Path: nimoy/ast_tools/ast_chain.py
# def apply(runner_context: RunnerContext, spec_location, node):
# 
# Path: nimoy/runner/metadata.py
# class RunnerContext:
# 
#     def __init__(self, use_power_assertions: bool = False):
#         self.use_power_assertions = use_power_assertions
# 
# Path: nimoy/runner/spec_finder.py
# class Location:
#     def __init__(self, suggested_location):
# 
#         # Format may be:
#         # - some_spec.py
#         # - some_spec.py::SpecName
#         # - some_spec.py::feature_name
#         # - some_spec.py::SpecName::feature_name
#         split_suggested_location = suggested_location.split("::")
# 
#         # some_spec.py
#         if len(split_suggested_location) == 1:
#             self.spec_path = split_suggested_location[0]
# 
#         # some_spec.py::SpecName or some_spec.py::feature_name
#         if len(split_suggested_location) == 2:
#             self.spec_path = split_suggested_location[0]
# 
#             # some_spec.py::SpecName
#             if split_suggested_location[1][0].isupper():
#                 self.spec_name = split_suggested_location[1]
# 
#             # some_spec.py::feature_name
#             else:
#                 self.feature_name = split_suggested_location[1]
# 
#         # some_spec.py::SpecName::feature_name
#         if len(split_suggested_location) == 3:
#             self.spec_path = split_suggested_location[0]
#             self.spec_name = split_suggested_location[1]
#             self.feature_name = split_suggested_location[2]
# 
# Path: nimoy/specification.py
# class Specification(TestCase, metaclass=DataDrivenSpecification):
# 
#     def __init__(self, methodName='runTest'):
#         super().__init__(methodName)
#         self.thrown_exceptions = []
# 
#     def _feature_block_context(self, block_name):
#         return FeatureBlock(block_name, self.thrown_exceptions)
# 
#     def _compare(self, left, right, comparison_type_name):
#         Compare().compare(left, right, comparison_type_name)
# 
#     def _power_assert(self, expression: Dict):
#         PowerAssertions().assert_and_raise(expression)
# 
#     def _assert_mock(self, number_of_invocations, mock, method, *args):
#         MockAssertions().assert_mock(number_of_invocations, mock, method, *args)
# 
#     def _exception_thrown(self, expected_exception_type):
#         return ExceptionAssertions().assert_exception(self.thrown_exceptions, expected_exception_type)


from unittest import mock
from nimoy.ast_tools import ast_chain
from nimoy.runner.metadata import RunnerContext
from nimoy.runner.spec_finder import Location
from nimoy.specification import Specification



class AstChainSpec(Specification):

    @mock.patch('nimoy.ast_tools.ast_chain.SpecTransformer')
    def apply_chain(self, spec_transformer_mock):
        with given:
            node = {}
        with when:
            spec_metadata = ast_chain.apply(RunnerContext(), Location('some_spec.py'), node)
        with then:
            isinstance(spec_metadata, list) == True

# Path: nimoy/ast_tools/ast_chain.py
# def apply(runner_context: RunnerContext, spec_location, node):
# 
# Path: nimoy/runner/metadata.py
# class RunnerContext:
# 
#     def __init__(self, use_power_assertions: bool = False):
#         self.use_power_assertions = use_power_assertions
# 
# Path: nimoy/runner/spec_finder.py
# class Location:
#     def __init__(self, suggested_location):
# 
#         # Format may be:
#         # - some_spec.py
#         # - some_spec.py::SpecName
#         # - some_spec.py::feature_name
#         # - some_spec.py::SpecName::feature_name
#         split_suggested_location = suggested_location.split("::")
# 
#         # some_spec.py
#         if len(split_suggested_location) == 1:
#             self.spec_path = split_suggested_location[0]
# 
#         # some_spec.py::SpecName or some_spec.py::feature_name
#         if len(split_suggested_location) == 2:
#             self.spec_path = split_suggested_location[0]
# 
#             # some_spec.py::SpecName
#             if split_suggested_location[1][0].isupper():
#                 self.spec_name = split_suggested_location[1]
# 
#             # some_spec.py::feature_name
#             else:
#                 self.feature_name = split_suggested_location[1]
# 
#         # some_spec.py::SpecName::feature_name
#         if len(split_suggested_location) == 3:
#             self.spec_path = split_suggested_location[0]
#             self.spec_name = split_suggested_location[1]
#             self.feature_name = split_suggested_location[2]
# 
# Path: nimoy/specification.py
# class Specification(TestCase, metaclass=DataDrivenSpecification):
# 
#     def __init__(self, methodName='runTest'):
#         super().__init__(methodName)
#         self.thrown_exceptions = []
# 
#     def _feature_block_context(self, block_name):
#         return FeatureBlock(block_name, self.thrown_exceptions)
# 
#     def _compare(self, left, right, comparison_type_name):
#         Compare().compare(left, right, comparison_type_name)
# 
#     def _power_assert(self, expression: Dict):
#         PowerAssertions().assert_and_raise(expression)
# 
#     def _assert_mock(self, number_of_invocations, mock, method, *args):
#         MockAssertions().assert_mock(number_of_invocations, mock, method, *args)
# 
#     def _exception_thrown(self, expected_exception_type):
#         return ExceptionAssertions().assert_exception(self.thrown_exceptions, expected_exception_type)


# Path: specs/nimoy/ast_tools/ast_chain_spec.py
from unittest import mock
from nimoy.ast_tools import ast_chain
from nimoy.runner.metadata import RunnerContext
from nimoy.runner.spec_finder import Location
from nimoy.specification import Specification




class AstChainSpec(Specification):

    @mock.patch('nimoy.ast_tools.ast_chain.SpecTransformer')
    def apply_chain(self, spec_transformer_mock):
        with given:
            node = {}
        with when:
            spec_metadata = ast_chain.apply(RunnerContext(), Location('some_spec.py'), node)
        with then:
            isinstance(spec_metadata, list) == True

            1 * spec_transformer_mock.return_value.visit(node)