# Path: sciunit/utils.py
# def use_backend_cache(original_function=None, cache_key_param=None):
#     """
#     Decorator for test functions (in particular `generate_prediction`) to cache
#     the function output on the first execution and return the output from the
#     cache without recomputing on any subsequent execution.
#     The function needs to take a model as an argument, and the caching relies on
#     the model's backend. If it doesn't have a backend the caching step is
#     skipped.
#     Per default, a test instance specific hash is used to link the model to the
#     test's function output. However, optionally, a custom hash key name can be
#     passed to the decorator to use the hash stored in
#     `self.params[<hash key name>]` instead (e.g. for using a shared cache for
#     redundant calculations on the same model across tests).
#     """
# 
#     def _decorate(function):
# 
#         @functools.wraps(function)
#         def wrapper(self, *args, **kwargs):
#             sig = inspect.signature(function)
#             if 'model' in kwargs:
#                 model = kwargs['model']
#             elif 'model' in sig.parameters.keys():
#                 model = args[list(sig.parameters.keys()).index('model')-1]
#             else:
#                 model = None
#                 warnings.warn("The decorator `use_backend_cache` can only "
#                               "be used for test class functions that get "
#                               "'model' as an argument! Caching is skipped.")
# 
#             cache_key = None
#             if cache_key_param:
#                 if cache_key_param in self.params:
#                     cache_key = self.params[cache_key_param]
#                 else:
#                     model = None
#                     warnings.warn("The value for the decorator arguement "
#                                   "cache_key_param value can not be found in "
#                                   "self.params! Caching is skipped.")
# 
#             function_output = self.get_backend_cache(model=model,
#                                                      key=cache_key)
# 
#             if function_output is None:
#                 function_output = function(self, *args, **kwargs)
#                 self.set_backend_cache(model=model,
#                                        function_output=function_output,
#                                        key=cache_key)
# 
#             return function_output
# 
#         return wrapper
# 
#     if original_function:
#         return _decorate(original_function)
#     else:
#         return _decorate


import tempfile
import unittest
import sciunit
import numpy as np
        import quantities as pq
from sciunit.utils import use_backend_cache
        from sciunit.utils import set_warnings_traceback, warn_with_traceback
        from sciunit.utils import NotebookTools
        from sciunit.base import log, strip_html
        from sciunit.utils import html_log
        from sciunit.utils import assert_dimensionless
        from sciunit.utils import dict_hash
        from sciunit.utils import import_module_from_path
        from sciunit.models.examples import ConstModel
        from io import StringIO
        from sciunit.utils import MockDevice
        from random import randint
        from sciunit.utils import memoize
        from sciunit.utils import class_intern
"""Unit tests for sciunit utility functions and classes"""




class CacheTestCase(unittest.TestCase):

    def test_basic_cache(self):
        class dummy_test(sciunit.Test):

            # The name of the cache key param determines the cache key location
            @use_backend_cache(cache_key_param='dummy_cache_key')
            def create_random_matrix(self, model):
                # Generate a random matrix that will land in cache
                return np.random.randint(0, 100, size=(5,5))

        class dummy_avg_test(dummy_test):

            default_params = {'dummy_cache_key': '1234'}


# Path: sciunit/utils.py
# def use_backend_cache(original_function=None, cache_key_param=None):
#     """
#     Decorator for test functions (in particular `generate_prediction`) to cache
#     the function output on the first execution and return the output from the
#     cache without recomputing on any subsequent execution.
#     The function needs to take a model as an argument, and the caching relies on
#     the model's backend. If it doesn't have a backend the caching step is
#     skipped.
#     Per default, a test instance specific hash is used to link the model to the
#     test's function output. However, optionally, a custom hash key name can be
#     passed to the decorator to use the hash stored in
#     `self.params[<hash key name>]` instead (e.g. for using a shared cache for
#     redundant calculations on the same model across tests).
#     """
# 
#     def _decorate(function):
# 
#         @functools.wraps(function)
#         def wrapper(self, *args, **kwargs):
#             sig = inspect.signature(function)
#             if 'model' in kwargs:
#                 model = kwargs['model']
#             elif 'model' in sig.parameters.keys():
#                 model = args[list(sig.parameters.keys()).index('model')-1]
#             else:
#                 model = None
#                 warnings.warn("The decorator `use_backend_cache` can only "
#                               "be used for test class functions that get "
#                               "'model' as an argument! Caching is skipped.")
# 
#             cache_key = None
#             if cache_key_param:
#                 if cache_key_param in self.params:
#                     cache_key = self.params[cache_key_param]
#                 else:
#                     model = None
#                     warnings.warn("The value for the decorator arguement "
#                                   "cache_key_param value can not be found in "
#                                   "self.params! Caching is skipped.")
# 
#             function_output = self.get_backend_cache(model=model,
#                                                      key=cache_key)
# 
#             if function_output is None:
#                 function_output = function(self, *args, **kwargs)
#                 self.set_backend_cache(model=model,
#                                        function_output=function_output,
#                                        key=cache_key)
# 
#             return function_output
# 
#         return wrapper
# 
#     if original_function:
#         return _decorate(original_function)
#     else:
#         return _decorate


# Path: sciunit/unit_test/utils_tests.py
import tempfile
import unittest
import sciunit
import numpy as np
        import quantities as pq
from sciunit.utils import use_backend_cache
        from sciunit.utils import set_warnings_traceback, warn_with_traceback
        from sciunit.utils import NotebookTools
        from sciunit.base import log, strip_html
        from sciunit.utils import html_log
        from sciunit.utils import assert_dimensionless
        from sciunit.utils import dict_hash
        from sciunit.utils import import_module_from_path
        from sciunit.models.examples import ConstModel
        from io import StringIO
        from sciunit.utils import MockDevice
        from random import randint
        from sciunit.utils import memoize
        from sciunit.utils import class_intern

"""Unit tests for sciunit utility functions and classes"""




class CacheTestCase(unittest.TestCase):

    def test_basic_cache(self):
        class dummy_test(sciunit.Test):

            # The name of the cache key param determines the cache key location
            @use_backend_cache(cache_key_param='dummy_cache_key')
            def create_random_matrix(self, model):
                # Generate a random matrix that will land in cache
                return np.random.randint(0, 100, size=(5,5))

        class dummy_avg_test(dummy_test):

            default_params = {'dummy_cache_key': '1234'}


            @use_backend_cache