"""Test suite for the profile module."""

import sys
import pstats
import unittest
from StringIO import StringIO
from test.test_support import run_unittest

import profile
from test.profilee import testfunc, timer


class ProfileTest(unittest.TestCase):

    profilerclass = profile.Profile
    methodnames = ['print_stats', 'print_callers', 'print_callees']
    expected_output = {}
    expected_list_sort_output = ':0(sort)'

    @classmethod
    def do_profiling(cls):
        results = []
        prof = cls.profilerclass(timer, 0.001)
        start_timer = timer()
        prof.runctx("testfunc()", globals(), locals())
        results.append(timer() - start_timer)
        for methodname in cls.methodnames:
            s = StringIO()
            stats = pstats.Stats(prof, stream=s)
            stats.strip_dirs().sort_stats("stdname")
            getattr(stats, methodname)()
            results.append(s.getvalue())
        return results

    def test_cprofile(self):
        results = self.do_profiling()
        self.assertEqual(results[0], 1000)
        for i, method in enumerate(self.methodnames):
            self.assertEqual(results[i+1], self.expected_output[method],
                             "Stats.%s output for %s doesn't fit expectation!" %
                             (method, self.profilerclass.__name__))

    def test_calling_conventions(self):
        # Issue #5330: profile and cProfile wouldn't report C functions called
        # with keyword arguments. We test all calling conventions.
        stmts = [
            "[].sort()",
            "[].sort(reverse=True)",
            "[].sort(*(None, None, True))",
            "[].sort(**dict(reverse=True))",
        ]
        for stmt in stmts:
            s = StringIO()
            prof = self.profilerclass(timer, 0.001)
            prof.runctx(stmt, globals(), locals())
            stats = pstats.Stats(prof, stream=s)
            stats.print_stats()
            res = s.getvalue()
            self.assertIn(self.expected_list_sort_output, res,
                "Profiling {0!r} didn't report list.sort:\n{1}".format(stmt, res))


def regenerate_expected_output(filename, cls):
    filename = filename.rstrip('co')
    print 'Regenerating %s...' % filename
    results = cls.do_profiling()

    newfile = []
    with open(filename, 'r') as f:
        for line in f:
            newfile.append(line)
            if line[:6] == '#--cut':
                break

    with open(filename, 'w') as f:
        f.writelines(newfile)
        for i, method in enumerate(cls.methodnames):
            f.write('%s.expected_output[%r] = """\\\n%s"""\n' % (
                cls.__name__, method, results[i+1]))
        f.write('\nif __name__ == "__main__":\n    main()\n')


def test_main():
    run_unittest(ProfileTest)

def main():
    if '-r' not in sys.argv:
        test_main()
    else:
        regenerate_expected_output(__file__, ProfileTest)


# Don't remove this comment. Everything below it is auto-generated.
#--cut--------------------------------------------------------------------------
ProfileTest.expected_output['print_stats'] = """\
         127 function calls (107 primitive calls) in 999.749 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        4   -0.004   -0.001   -0.004   -0.001 :0(append)
        4   -0.004   -0.001   -0.004   -0.001 :0(exc_info)
       12   -0.024   -0.002   11.964    0.997 :0(hasattr)
        8   -0.008   -0.001   -0.008   -0.001 :0(range)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
        1   -0.002   -0.002  999.751  999.751 <string>:1(<module>)
        0    0.000             0.000          profile:0(profiler)
        1   -0.002   -0.002  999.749  999.749 profile:0(testfunc())
       28   27.972    0.999   27.972    0.999 profilee.py:110(__getattr__)
        1  269.996  269.996  999.753  999.753 profilee.py:25(testfunc)
     23/3  149.937    6.519  169.917   56.639 profilee.py:35(factorial)
       20   19.980    0.999   19.980    0.999 profilee.py:48(mul)
        2   39.986   19.993  599.814  299.907 profilee.py:55(helper)
        4  115.984   28.996  119.964   29.991 profilee.py:73(helper1)
        2   -0.006   -0.003  139.942   69.971 profilee.py:84(helper2_indirect)
        8  311.976   38.997  399.896   49.987 profilee.py:88(helper2)
        8   63.968    7.996   79.944    9.993 profilee.py:98(subhelper)


"""
ProfileTest.expected_output['print_callers'] = """\
   Ordered by: standard name

Function                          was called by...
:0(append)                        <- profilee.py:73(helper1)(4)  119.964
:0(exc_info)                      <- profilee.py:73(helper1)(4)  119.964
:0(hasattr)                       <- profilee.py:73(helper1)(4)  119.964
                                     profilee.py:88(helper2)(8)  399.896
:0(range)                         <- profilee.py:98(subhelper)(8)   79.944
:0(setprofile)                    <- profile:0(testfunc())(1)  999.749
<string>:1(<module>)              <- profile:0(testfunc())(1)  999.749
profile:0(profiler)               <-
profile:0(testfunc())             <- profile:0(profiler)(1)    0.000
profilee.py:110(__getattr__)      <- :0(hasattr)(12)   11.964
                                     profilee.py:98(subhelper)(16)   79.944
profilee.py:25(testfunc)          <- <string>:1(<module>)(1)  999.751
profilee.py:35(factorial)         <- profilee.py:25(testfunc)(1)  999.753
                                     profilee.py:35(factorial)(20)  169.917
                                     profilee.py:84(helper2_indirect)(2)  139.942
profilee.py:48(mul)               <- profilee.py:35(factorial)(20)  169.917
profilee.py:55(helper)            <- profilee.py:25(testfunc)(2)  999.753
profilee.py:73(helper1)           <- profilee.py:55(helper)(4)  599.814
profilee.py:84(helper2_indirect)  <- profilee.py:55(helper)(2)  599.814
profilee.py:88(helper2)           <- profilee.py:55(helper)(6)  599.814
                                     profilee.py:84(helper2_indirect)(2)  139.942
profilee.py:98(subhelper)         <- profilee.py:88(helper2)(8)  399.896


"""
ProfileTest.expected_output['print_callees'] = """\
   Ordered by: standard name

Function                          called...
:0(append)                        ->
:0(exc_info)                      ->
:0(hasattr)                       -> profilee.py:110(__getattr__)(12)   27.972
:0(range)                         ->
:0(setprofile)                    ->
<string>:1(<module>)              -> profilee.py:25(testfunc)(1)  999.753
profile:0(profiler)               -> profile:0(testfunc())(1)  999.749
profile:0(testfunc())             -> :0(setprofile)(1)    0.000
                                     <string>:1(<module>)(1)  999.751
profilee.py:110(__getattr__)      ->
profilee.py:25(testfunc)          -> profilee.py:35(factorial)(1)  169.917
                                     profilee.py:55(helper)(2)  599.814
profilee.py:35(factorial)         -> profilee.py:35(factorial)(20)  169.917
                                     profilee.py:48(mul)(20)   19.980
profilee.py:48(mul)               ->
profilee.py:55(helper)            -> profilee.py:73(helper1)(4)  119.964
                                     profilee.py:84(helper2_indirect)(2)  139.942
                                     profilee.py:88(helper2)(6)  399.896
profilee.py:73(helper1)           -> :0(append)(4)   -0.004
                                     :0(exc_info)(4)   -0.004
                                     :0(hasattr)(4)   11.964
profilee.py:84(helper2_indirect)  -> profilee.py:35(factorial)(2)  169.917
                                     profilee.py:88(helper2)(2)  399.896
profilee.py:88(helper2)           -> :0(hasattr)(8)   11.964
                                     profilee.py:98(subhelper)(8)   79.944
profilee.py:98(subhelper)         -> :0(range)(8)   -0.008
                                     profilee.py:110(__getattr__)(16)   27.972


"""

if __name__ == "__main__":
    main()
