"""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()
