# 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_executor.py
# class SpecExecutor:
#     def __init__(self, execution_framework) -> None:
#         super().__init__()
#         self.execution_framework = execution_framework
# 
#     def execute(self, specs):
#         for spec_metadata in specs:
#             spec_class_module = spec_metadata.owning_module
# 
#             for spec_feature in spec_metadata.features:
#                 self.execution_framework.append_test(spec_class_module(spec_feature))
# 
#         return self.execution_framework.run()
# 
# Path: nimoy/runner/spec_finder.py
# class SpecFinder:
#     def __init__(self, working_directory) -> None:
#         super().__init__()
#         self.working_directory = working_directory
#         self.spec_locations = []
# 
#     def find(self, suggested_locations):
#         if not suggested_locations:
#             suggested_locations.append(self.working_directory)
#         self._find_specs_in_suggested_locations(suggested_locations)
# 
#         return self.spec_locations
# 
#     def _find_specs_in_suggested_locations(self, suggested_locations):
# 
#         for suggested_location in suggested_locations:
#             normalized_suggested_location = self._normalize_suggested_location(suggested_location)
# 
#             if 'spec.py' in normalized_suggested_location:
#                 self.spec_locations.append(Location(normalized_suggested_location))
#             else:
#                 self._find_specs_in_directory(normalized_suggested_location)
# 
#     def _normalize_suggested_location(self, suggested_location):
# 
#         if os.path.isabs(suggested_location):
#             return suggested_location
#         return os.path.join(self.working_directory, suggested_location)
# 
#     def _find_specs_in_directory(self, directory):
#         for root, _, file_names in os.walk(directory):
#             for filename in fnmatch.filter(file_names, '*spec.py'):
#                 self.spec_locations.append(Location(os.path.join(root, filename)))
# 
# Path: nimoy/runner/spec_loader.py
# class SpecLoader:
#     def __init__(self, runner_context: RunnerContext, ast_chain) -> None:
#         super().__init__()
#         self.runner_context = runner_context
#         self.ast_chain = ast_chain
# 
#     def load(self, spec_locations_and_contents):
#         def specs():
#             for spec_location, text in spec_locations_and_contents:
#                 node = ast.parse(text, mode='exec')
# 
#                 metadata_of_specs_from_node = self.ast_chain.apply(self.runner_context, spec_location, node)
#                 ast.fix_missing_locations(node)
#                 compiled = compile(node, spec_location.spec_path, 'exec')
# 
#                 spec_namespace = {}
#                 exec(compiled, spec_namespace)
# 
#                 for spec_metadata in metadata_of_specs_from_node:
#                     spec_metadata.set_owning_module(spec_namespace[spec_metadata.name])
#                     yield spec_metadata
# 
#         return specs()
# 
# Path: nimoy/runner/spec_reader.py
# class SpecReader:
#     def __init__(self, resource_reader) -> None:
#         super().__init__()
#         self.resource_reader = resource_reader
# 
#     def read(self, spec_locations):
#         def spec_contents():
#             for spec_file_location in spec_locations:
#                 text = self.resource_reader.read(spec_file_location.spec_path)
#                 yield (spec_file_location, text)
# 
#         return spec_contents()


import argparse
import os
from nimoy.ast_tools import ast_chain
from nimoy.runner import fs_resource_reader
from nimoy.runner.metadata import RunnerContext
from nimoy.runner.spec_executor import SpecExecutor
from nimoy.runner.spec_finder import SpecFinder
from nimoy.runner.spec_loader import SpecLoader
from nimoy.runner.spec_reader import SpecReader



class SpecRunner:
    def run(self, execution_framework):
        parser = argparse.ArgumentParser(prog='nimoy', description='Run a suite of Nimoy specs.')
        parser.add_argument('--power-assertions', metavar='P', type=bool, nargs=1, default=False,
                            help="Should Nimoy evaluate comparison expressions using power assertions (beta)")
        parser.add_argument('specs', metavar='S', type=str, nargs='*',
                            help="""A path to a spec file to execute or a directory to scan for spec files.
                                    When naming a file it is possible to select which spec or feature to run. some_spec.py[::SpecName[::feature_name]]
                                    """)

        args = parser.parse_args()

        spec_locations = SpecRunner._find_specs(args)
        spec_locations_and_contents = SpecRunner._read_specs(spec_locations)
        return SpecRunner._run_on_contents(RunnerContext(use_power_assertions=args.power_assertions),
                                           execution_framework, spec_locations_and_contents)

    @staticmethod

# 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_executor.py
# class SpecExecutor:
#     def __init__(self, execution_framework) -> None:
#         super().__init__()
#         self.execution_framework = execution_framework
# 
#     def execute(self, specs):
#         for spec_metadata in specs:
#             spec_class_module = spec_metadata.owning_module
# 
#             for spec_feature in spec_metadata.features:
#                 self.execution_framework.append_test(spec_class_module(spec_feature))
# 
#         return self.execution_framework.run()
# 
# Path: nimoy/runner/spec_finder.py
# class SpecFinder:
#     def __init__(self, working_directory) -> None:
#         super().__init__()
#         self.working_directory = working_directory
#         self.spec_locations = []
# 
#     def find(self, suggested_locations):
#         if not suggested_locations:
#             suggested_locations.append(self.working_directory)
#         self._find_specs_in_suggested_locations(suggested_locations)
# 
#         return self.spec_locations
# 
#     def _find_specs_in_suggested_locations(self, suggested_locations):
# 
#         for suggested_location in suggested_locations:
#             normalized_suggested_location = self._normalize_suggested_location(suggested_location)
# 
#             if 'spec.py' in normalized_suggested_location:
#                 self.spec_locations.append(Location(normalized_suggested_location))
#             else:
#                 self._find_specs_in_directory(normalized_suggested_location)
# 
#     def _normalize_suggested_location(self, suggested_location):
# 
#         if os.path.isabs(suggested_location):
#             return suggested_location
#         return os.path.join(self.working_directory, suggested_location)
# 
#     def _find_specs_in_directory(self, directory):
#         for root, _, file_names in os.walk(directory):
#             for filename in fnmatch.filter(file_names, '*spec.py'):
#                 self.spec_locations.append(Location(os.path.join(root, filename)))
# 
# Path: nimoy/runner/spec_loader.py
# class SpecLoader:
#     def __init__(self, runner_context: RunnerContext, ast_chain) -> None:
#         super().__init__()
#         self.runner_context = runner_context
#         self.ast_chain = ast_chain
# 
#     def load(self, spec_locations_and_contents):
#         def specs():
#             for spec_location, text in spec_locations_and_contents:
#                 node = ast.parse(text, mode='exec')
# 
#                 metadata_of_specs_from_node = self.ast_chain.apply(self.runner_context, spec_location, node)
#                 ast.fix_missing_locations(node)
#                 compiled = compile(node, spec_location.spec_path, 'exec')
# 
#                 spec_namespace = {}
#                 exec(compiled, spec_namespace)
# 
#                 for spec_metadata in metadata_of_specs_from_node:
#                     spec_metadata.set_owning_module(spec_namespace[spec_metadata.name])
#                     yield spec_metadata
# 
#         return specs()
# 
# Path: nimoy/runner/spec_reader.py
# class SpecReader:
#     def __init__(self, resource_reader) -> None:
#         super().__init__()
#         self.resource_reader = resource_reader
# 
#     def read(self, spec_locations):
#         def spec_contents():
#             for spec_file_location in spec_locations:
#                 text = self.resource_reader.read(spec_file_location.spec_path)
#                 yield (spec_file_location, text)
# 
#         return spec_contents()


# Path: nimoy/spec_runner.py
import argparse
import os
from nimoy.ast_tools import ast_chain
from nimoy.runner import fs_resource_reader
from nimoy.runner.metadata import RunnerContext
from nimoy.runner.spec_executor import SpecExecutor
from nimoy.runner.spec_finder import SpecFinder
from nimoy.runner.spec_loader import SpecLoader
from nimoy.runner.spec_reader import SpecReader




class SpecRunner:
    def run(self, execution_framework):
        parser = argparse.ArgumentParser(prog='nimoy', description='Run a suite of Nimoy specs.')
        parser.add_argument('--power-assertions', metavar='P', type=bool, nargs=1, default=False,
                            help="Should Nimoy evaluate comparison expressions using power assertions (beta)")
        parser.add_argument('specs', metavar='S', type=str, nargs='*',
                            help="""A path to a spec file to execute or a directory to scan for spec files.
                                    When naming a file it is possible to select which spec or feature to run. some_spec.py[::SpecName[::feature_name]]
                                    """)

        args = parser.parse_args()

        spec_locations = SpecRunner._find_specs(args)
        spec_locations_and_contents = SpecRunner._read_specs(spec_locations)
        return SpecRunner._run_on_contents(RunnerContext(use_power_assertions=args.power_assertions),
                                           execution_framework, spec_locations_and_contents)

    @staticmethod

    def _run_on_contents(runner_context: RunnerContext, execution_framework, spec_locations_and_contents):