text: import inspect
  import os
  
  import jug.task
  from .task_reset import task_reset_at_exit, task_reset
  from .utils import simple_execute
  
  
  _jugdir = os.path.abspath(inspect.getfile(inspect.currentframe()))
  _jugdir = os.path.join(os.path.dirname(_jugdir), 'jugfiles')
  
  
  Task = jug.task.Task
  
  def add1(x):
      return x + 1
  def add2(x):
      return x + 2
  
  def _assert_tsorted(tasks):
      from itertools import chain
      for i,ti in enumerate(tasks):
          for j,tj in enumerate(tasks[i+1:]):
              for dep in chain(ti.args, ti.kwargs.values()):
                  if type(dep) is list:
                      assert tj not in dep
                  else:
                      assert tj is not dep
  
  @task_reset
  def test_topological_sort():
      bases = [jug.task.Task(add1,i) for i in range(10)]
      derived = [jug.task.Task(add1,t) for t in bases]
      derived2 = [jug.task.Task(add1,t) for t in derived]
      derived3 = [jug.task.Task(add1,t) for t in derived]
      
      alltasks = bases + derived
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
      
      alltasks.reverse()
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
      alltasks = bases + derived
      alltasks.reverse()
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
      alltasks = derived + bases
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
      alltasks = derived + bases + derived2
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived) + len(derived2)
      _assert_tsorted(alltasks)
  
      alltasks = derived + bases + derived2 + derived3
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived) + len(derived2) + len(derived3)
      _assert_tsorted(alltasks)
  
  @task_reset
  def test_topological_sort_kwargs():
      def add2(x):
          return x + 2
      def sumlst(lst,param):
          return sum(lst)
  
      bases = [jug.task.Task(add2,x=i) for i in range(10)]
      derived = [jug.task.Task(sumlst,lst=bases,param=p) for p in range(4)]
  
      alltasks = bases + derived
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
      
      alltasks.reverse()
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
      alltasks = bases + derived
      alltasks.reverse()
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
      alltasks = derived + bases
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(bases) + len(derived)
      _assert_tsorted(alltasks)
  
  def data():
      return list(range(20))
  def mult(r,f):
      return [f*rr for rr in r]
  def reduce(r):
      return sum(r)
  
  @task_reset
  def test_topological_sort_canrun():
      Task = jug.task.Task
      input = Task(data)
      for f in range(80):
          Task(reduce, Task(mult,input,f))
  
      alltasks = jug.task.alltasks
      jug.task.topological_sort(alltasks)
      assert len(alltasks) == len(set(t.hash() for t in alltasks))
      for t in alltasks:
          assert t.can_run()
          t.run()
  
  @task_reset
  def test_load_after_run():
      T = jug.task.Task(add1,1)
      T.run()
      assert T.can_load()
  
  @task_reset
  def test_hash_same_func():
      T0 = jug.task.Task(add1,0)
      T1 = jug.task.Task(add1,1)
  
      assert T0.hash() != T1.hash()
      
  @task_reset
  def test_hash_different_func():
      T0 = jug.task.Task(add1,0)
      T1 = jug.task.Task(add2,0)
  
      assert T0.hash() != T1.hash()
  
  
  @task_reset
  def test_taskgenerator():
      @jug.task.TaskGenerator
      def double(x):
          return 2*x
      T=double(2)
      assert type(T) == jug.task.Task
  
  
  @task_reset
  def test_unload():
      T0 = jug.task.Task(add1,0)
      assert not hasattr(T0, '_result')
      assert T0.can_run()
      T0.run()
      assert hasattr(T0, '_result')
      assert T0.result == 1
      T0.unload()
      assert T0.result == 1
  
  @task_reset
  def test_unload_recursive():
      T0 = jug.task.Task(add1,0)
      T1 = jug.task.Task(add1,T0)
      T2 = jug.task.Task(add1,T1)
      assert not hasattr(T0, '_result')
      T0.run()
      T1.run()
      T2.run()
      assert hasattr(T0, '_result')
  
      T2.unload_recursive()
      assert not hasattr(T0, '_result')
  
  def identity(x):
      return x
  
  @task_reset
  def test_cachedfunction():
      assert jug.task.CachedFunction(identity,123) == 123
      assert jug.task.CachedFunction(identity,'mixture') == 'mixture'
  
  @task_reset
  def test_npyload():
      import numpy as np
      A = np.arange(23)
      assert np.all(jug.task.CachedFunction(identity,A) == A)
  
  @jug.task.TaskGenerator
  def double(x):
      return 2 * x
  
  @task_reset
  def test_value():
      two = double(1)
      four = double(two)
      eight = double(four)
      two.run()
      four.run()
      eight.run()
      assert jug.task.value(eight) == 8
  
  @task_reset
  def test_dict_sort_run():
      tasks = [double(1), double(2), Task(identity,2) ]
      tasks += [Task(identity,{ 'one' : tasks[2], 'two' : tasks[0], 'three' : { 1 : tasks[1], 0 : tasks[0] }})]
      jug.task.topological_sort(tasks)
      for t in tasks:
          assert t.can_run()
          t.run()
      assert tasks[-1].result == { 'one' : 2, 'two' : 2, 'three' : {1 : 4, 0: 2}}
  
  @task_reset
  def test_unload_recursive_result_property():
      two = double(1)
      four = double(two)
      two.run()
      four.run()
      four.unload_recursive ()
      assert not hasattr(four, '_result')
      assert not hasattr(two, '_result')
  
  # Crashed in version 0.7.3
  @task_reset
  def test_unload_wnoresult():
      t = Task(add2, 3)
      t.unload()
  
  @task_reset
  def test_starts_unloaded():
      t = Task(add2, 3)
      assert not t.is_loaded()
  
  @task_reset
  def test__str__repr__():
      t = Task(add2, 3)
      assert str(t).find('add2') >= 0
      assert repr(t).find('add2') >= 0
      assert repr(t).find('3') >= 0
  
  
  def add_tuple(a_b):
      a,b = a_b
      return a + b
  
  @task_reset
  def test_unload_recursive_tuple():
      T0 = jug.task.Task(add1,0)
      T1 = jug.task.Task(add1,T0)
      T2 = jug.task.Task(add_tuple,(T0,T1))
      T3 = jug.task.Task(add1, T2)
      assert not hasattr(T0, '_result')
      T0.run()
      T1.run()
      T2.run()
      T3.run()
      assert hasattr(T0, '_result')
  
      T3.unload_recursive()
      assert not hasattr(T0, '_result')
  
  @task_reset
  def test_builtin_function():
      import numpy as np
      jugfile = os.path.join(_jugdir, 'builtin_function.py')
      store, space = jug.jug.init(jugfile, 'dict_store')
      simple_execute()
      a8 = jug.task.value(space['a8'])
      assert np.all(a8 == np.arange(8))
  