# Path: honeybadger/payload.py
# def error_payload(exception, exc_traceback, config):
#     def _filename(name):
#         return name.replace(config.project_root, '[PROJECT_ROOT]')
# 
#     def is_not_honeybadger_frame(frame):
#         # TODO: is there a better way to do this?
#         # simply looking for 'honeybadger' in the path doesn't seem
#         # specific enough but this approach seems too specific and
#         # would need to be updated if we re-factored the call stack
#         # for building a payload.
#         return not ('honeybadger' in frame[0] and frame[2] in ['notify', '_send_notice', 'create_payload', 'error_payload'])
# 
# 
#     if exc_traceback:
#         tb = traceback.extract_tb(exc_traceback)
#     else:
#         tb = [f for f in traceback.extract_stack() if is_not_honeybadger_frame(f)]
# 
#     logger.debug(tb)
# 
#     payload = {
#         'class': type(exception) is dict and exception['error_class'] or exception.__class__.__name__,
#         'message': type(exception) is dict and exception['error_message'] or str(exception),
#         'backtrace': [dict(number=f[1], file=_filename(f[0]), method=f[2], source=read_source(f)) for f in reversed(tb)]
#     }
# 
#     return payload
# 
# Path: honeybadger/payload.py
# def server_payload(config):
#     return {
#         'project_root': config.project_root,
#         'environment_name': config.environment,
#         'hostname': config.hostname,
#         'time': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
#         'pid': os.getpid(),
#         'stats': stats_payload()
#     }
# 
# Path: honeybadger/config.py
# class Configuration(object):
#     DEVELOPMENT_ENVIRONMENTS = ['development', 'dev', 'test']
# 
#     OPTIONS = (
#         ('api_key', str),
#         ('project_root', str),
#         ('environment', str),
#         ('hostname', str),
#         ('endpoint', str),
#         ('params_filters', list),
#         ('force_report_data', bool),
#         ('force_sync', bool),
#         ('excluded_exceptions', list)
#     )
# 
#     def __init__(self, *args, **kwargs):
#         self.api_key = ''
#         self.project_root = os.getcwd()
#         self.environment = 'production'
#         self.hostname = socket.gethostname()
#         self.endpoint = 'https://api.honeybadger.io'
#         self.params_filters = ['password', 'password_confirmation', 'credit_card', 'CSRF_COOKIE']
#         self.force_report_data = False
#         self.force_sync = self.is_aws_lambda_environment
#         self.excluded_exceptions = []
#         
#         self.set_12factor_config()
#         self.set_config_from_dict(kwargs)
# 
#     def set_12factor_config(self):
#         for option in list(zip(*self.OPTIONS))[0]:
#             val = os.environ.get('HONEYBADGER_{}'.format(option.upper()), getattr(self, option))
#             option_types = dict(self.OPTIONS)
# 
#             try:
#                 if option_types[option] is list:
#                     val = val.split(',')
#                 elif option_types[option] is int:
#                     val = int(val)
#                 elif option_types[option] is bool:
#                     val = bool(val)
#             except:
#                 pass
# 
# 
#             setattr(self, option, val)
# 
#     def set_config_from_dict(self, config):
#         for (key, value) in iteritems(config):
#             if key in list(zip(*self.OPTIONS))[0]:
#                 setattr(self, key, value)
# 
#     def is_dev(self):
#         """Returns wether you are in a dev environment or not
# 
#         A dev environment is defined in the constant DEVELOPMENT_ENVIRONMENTS
# 
#         :rtype: bool
#         """
#         return self.environment in self.DEVELOPMENT_ENVIRONMENTS
# 
#     @property
#     def is_aws_lambda_environment(self):
#         """
#         Checks if you are in an AWS Lambda environment by checking for the existence
#         of "AWS_LAMBDA_FUNCTION_NAME" in the environment variables.
# 
#         :rtype: bool
#         """
#         return os.environ.get("AWS_LAMBDA_FUNCTION_NAME") is not  None


from six.moves import range
from six.moves import zip
from contextlib import contextmanager
from honeybadger.payload import error_payload
from honeybadger.payload import server_payload
from honeybadger.config import Configuration
from mock import patch
from nose.tools import eq_, ok_
import os
import sys
        payload = error_payload(dict(error_class='Exception', error_message='Test'), None, config)
        expected = dict(zip(range(2, 9), ["Line {}\n".format(x) for x in range(2, 9)]))
        eq_(traceback_mock.call_count, 1)
        eq_(payload['backtrace'][0]['source'], expected)


@patch('os.path.isfile', return_value=False)
def test_error_payload_source_missing_file(_isfile):
    with mock_traceback(line_no=5) as traceback_mock:
        config = Configuration()
        payload = error_payload(
            dict(error_class='Exception', error_message='Test'), None, config)
        eq_(payload['backtrace'][0]['source'], {})


def test_server_payload():
    config = Configuration(project_root=os.path.dirname(__file__), environment='test', hostname='test.local')
    payload = server_payload(config)

    eq_(payload['project_root'], os.path.dirname(__file__))
    eq_(payload['environment_name'], 'test')
    eq_(payload['hostname'], 'test.local')
    eq_(payload['pid'], os.getpid())
    assert type(payload['stats']['mem']['total']) == float
    assert type(payload['stats']['mem']['free']) == float

def test_psutil_is_optional():
    config = Configuration()

    with patch.dict(sys.modules, {'psutil':None}):

# Path: honeybadger/payload.py
# def error_payload(exception, exc_traceback, config):
#     def _filename(name):
#         return name.replace(config.project_root, '[PROJECT_ROOT]')
# 
#     def is_not_honeybadger_frame(frame):
#         # TODO: is there a better way to do this?
#         # simply looking for 'honeybadger' in the path doesn't seem
#         # specific enough but this approach seems too specific and
#         # would need to be updated if we re-factored the call stack
#         # for building a payload.
#         return not ('honeybadger' in frame[0] and frame[2] in ['notify', '_send_notice', 'create_payload', 'error_payload'])
# 
# 
#     if exc_traceback:
#         tb = traceback.extract_tb(exc_traceback)
#     else:
#         tb = [f for f in traceback.extract_stack() if is_not_honeybadger_frame(f)]
# 
#     logger.debug(tb)
# 
#     payload = {
#         'class': type(exception) is dict and exception['error_class'] or exception.__class__.__name__,
#         'message': type(exception) is dict and exception['error_message'] or str(exception),
#         'backtrace': [dict(number=f[1], file=_filename(f[0]), method=f[2], source=read_source(f)) for f in reversed(tb)]
#     }
# 
#     return payload
# 
# Path: honeybadger/payload.py
# def server_payload(config):
#     return {
#         'project_root': config.project_root,
#         'environment_name': config.environment,
#         'hostname': config.hostname,
#         'time': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
#         'pid': os.getpid(),
#         'stats': stats_payload()
#     }
# 
# Path: honeybadger/config.py
# class Configuration(object):
#     DEVELOPMENT_ENVIRONMENTS = ['development', 'dev', 'test']
# 
#     OPTIONS = (
#         ('api_key', str),
#         ('project_root', str),
#         ('environment', str),
#         ('hostname', str),
#         ('endpoint', str),
#         ('params_filters', list),
#         ('force_report_data', bool),
#         ('force_sync', bool),
#         ('excluded_exceptions', list)
#     )
# 
#     def __init__(self, *args, **kwargs):
#         self.api_key = ''
#         self.project_root = os.getcwd()
#         self.environment = 'production'
#         self.hostname = socket.gethostname()
#         self.endpoint = 'https://api.honeybadger.io'
#         self.params_filters = ['password', 'password_confirmation', 'credit_card', 'CSRF_COOKIE']
#         self.force_report_data = False
#         self.force_sync = self.is_aws_lambda_environment
#         self.excluded_exceptions = []
#         
#         self.set_12factor_config()
#         self.set_config_from_dict(kwargs)
# 
#     def set_12factor_config(self):
#         for option in list(zip(*self.OPTIONS))[0]:
#             val = os.environ.get('HONEYBADGER_{}'.format(option.upper()), getattr(self, option))
#             option_types = dict(self.OPTIONS)
# 
#             try:
#                 if option_types[option] is list:
#                     val = val.split(',')
#                 elif option_types[option] is int:
#                     val = int(val)
#                 elif option_types[option] is bool:
#                     val = bool(val)
#             except:
#                 pass
# 
# 
#             setattr(self, option, val)
# 
#     def set_config_from_dict(self, config):
#         for (key, value) in iteritems(config):
#             if key in list(zip(*self.OPTIONS))[0]:
#                 setattr(self, key, value)
# 
#     def is_dev(self):
#         """Returns wether you are in a dev environment or not
# 
#         A dev environment is defined in the constant DEVELOPMENT_ENVIRONMENTS
# 
#         :rtype: bool
#         """
#         return self.environment in self.DEVELOPMENT_ENVIRONMENTS
# 
#     @property
#     def is_aws_lambda_environment(self):
#         """
#         Checks if you are in an AWS Lambda environment by checking for the existence
#         of "AWS_LAMBDA_FUNCTION_NAME" in the environment variables.
# 
#         :rtype: bool
#         """
#         return os.environ.get("AWS_LAMBDA_FUNCTION_NAME") is not  None


# Path: honeybadger/tests/test_payload.py
from six.moves import range
from six.moves import zip
from contextlib import contextmanager
from honeybadger.payload import error_payload
from honeybadger.payload import server_payload
from honeybadger.config import Configuration
from mock import patch
from nose.tools import eq_, ok_
import os
import sys

        payload = error_payload(dict(error_class='Exception', error_message='Test'), None, config)
        expected = dict(zip(range(2, 9), ["Line {}\n".format(x) for x in range(2, 9)]))
        eq_(traceback_mock.call_count, 1)
        eq_(payload['backtrace'][0]['source'], expected)


@patch('os.path.isfile', return_value=False)
def test_error_payload_source_missing_file(_isfile):
    with mock_traceback(line_no=5) as traceback_mock:
        config = Configuration()
        payload = error_payload(
            dict(error_class='Exception', error_message='Test'), None, config)
        eq_(payload['backtrace'][0]['source'], {})


def test_server_payload():
    config = Configuration(project_root=os.path.dirname(__file__), environment='test', hostname='test.local')
    payload = server_payload(config)

    eq_(payload['project_root'], os.path.dirname(__file__))
    eq_(payload['environment_name'], 'test')
    eq_(payload['hostname'], 'test.local')
    eq_(payload['pid'], os.getpid())
    assert type(payload['stats']['mem']['total']) == float
    assert type(payload['stats']['mem']['free']) == float

def test_psutil_is_optional():
    config = Configuration()

    with patch.dict(sys.modules, {'psutil':None}):

        payload = server_payload(config)