# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for the fake module."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import inspect
import six
import unittest

from services import cachemanager_svc
from services import config_svc
from services import features_svc
from services import issue_svc
from services import project_svc
from services import star_svc
from services import user_svc
from services import usergroup_svc
from testing import fake

fake_class_map = {
    fake.AbstractStarService: star_svc.AbstractStarService,
    fake.CacheManager: cachemanager_svc.CacheManager,
    fake.ProjectService: project_svc.ProjectService,
    fake.ConfigService: config_svc.ConfigService,
    fake.IssueService: issue_svc.IssueService,
    fake.UserGroupService: usergroup_svc.UserGroupService,
    fake.UserService: user_svc.UserService,
    fake.FeaturesService: features_svc.FeaturesService,
    }


class FakeMetaTest(unittest.TestCase):

  def testFunctionsHaveSameSignatures(self):
    """Verify that the fake class methods match the real ones."""
    for fake_cls, real_cls in fake_class_map.items():
      fake_attrs = set(dir(fake_cls))
      real_attrs = set(dir(real_cls))
      both_attrs = fake_attrs.intersection(real_attrs)
      to_test = [x for x in both_attrs if '__' not in x]
      for name in to_test:
        real_attr = getattr(real_cls, name)
        if six.PY2:
          assert inspect.ismethod(real_attr)
        else:
          assert inspect.isfunction(real_attr)
        real_spec = inspect.getfullargspec(real_attr)
        fake_spec = inspect.getfullargspec(getattr(fake_cls, name))
        # check same number of args and kwargs
        real_kw_len = len(real_spec[3]) if real_spec[3] else 0
        fake_kw_len = len(fake_spec[3]) if fake_spec[3] else 0

        self.assertEqual(
            len(real_spec[0]) - real_kw_len,
            len(fake_spec[0]) - fake_kw_len,
            'Unequal number of args on %s.%s' % (fake_cls.__name__, name))
        self.assertEqual(
            real_kw_len, fake_kw_len,
            'Unequal number of kwargs on %s.%s' % (fake_cls.__name__, name))
        if real_kw_len:
          self.assertEqual(
              real_spec[0][-real_kw_len:], fake_spec[0][-fake_kw_len:],
              'Mismatched kwargs on %s.%s' % (fake_cls.__name__, name))
        self.assertEqual(
            real_spec[3], fake_spec[3],
            'Mismatched kwarg defaults on %s.%s' % (fake_cls.__name__, name))
