#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Unit tests for the contents of mock_calls.py.
"""

import logging
import os
import unittest

from devil import devil_env
from devil.android.sdk import version_codes
from devil.utils import mock_calls

with devil_env.SysPath(devil_env.PYMOCK_PATH):
  import mock  # pylint: disable=import-error


class _DummyAdb(object):

  def __str__(self):
    return '0123456789abcdef'

  def Push(self, host_path, device_path):
    logging.debug('(device %s) pushing %r to %r', self, host_path, device_path)

  def IsOnline(self):
    logging.debug('(device %s) checking device online', self)
    return True

  def Shell(self, cmd):
    logging.debug('(device %s) running command %r', self, cmd)
    return "nice output\n"

  def Reboot(self):
    logging.debug('(device %s) rebooted!', self)

  @property
  def build_version_sdk(self):
    logging.debug('(device %s) getting build_version_sdk', self)
    return version_codes.LOLLIPOP


class TestCaseWithAssertCallsTest(mock_calls.TestCase):

  def setUp(self):
    self.adb = _DummyAdb()

  def ShellError(self):
    def action(cmd):
      raise ValueError('(device %s) command %r is not nice' % (self.adb, cmd))
    return action

  def get_answer(self):
    logging.debug("called 'get_answer' of %r object", self)
    return 42

  def echo(self, thing):
    logging.debug("called 'echo' of %r object", self)
    return thing

  def testCallTarget_succeds(self):
    self.assertEquals(self.adb.Shell,
                      self.call_target(self.call.adb.Shell))

  def testCallTarget_failsExternal(self):
    with self.assertRaises(ValueError):
      self.call_target(mock.call.sys.getcwd)

  def testCallTarget_failsUnknownAttribute(self):
    with self.assertRaises(AttributeError):
      self.call_target(self.call.adb.Run)

  def testCallTarget_failsIntermediateCalls(self):
    with self.assertRaises(AttributeError):
      self.call_target(self.call.adb.RunShell('cmd').append)

  def testPatchCall_method(self):
    self.assertEquals(42, self.get_answer())
    with self.patch_call(self.call.get_answer, return_value=123):
      self.assertEquals(123, self.get_answer())
    self.assertEquals(42, self.get_answer())

  def testPatchCall_attribute_method(self):
    with self.patch_call(self.call.adb.Shell, return_value='hello'):
      self.assertEquals('hello', self.adb.Shell('echo hello'))

  def testPatchCall_global(self):
    with self.patch_call(mock.call.os.getcwd, return_value='/some/path'):
      self.assertEquals('/some/path', os.getcwd())

  def testPatchCall_withSideEffect(self):
    with self.patch_call(self.call.adb.Shell, side_effect=ValueError):
      with self.assertRaises(ValueError):
        self.adb.Shell('echo hello')

  def testPatchCall_property(self):
    self.assertEquals(version_codes.LOLLIPOP, self.adb.build_version_sdk)
    with self.patch_call(
        self.call.adb.build_version_sdk,
        return_value=version_codes.KITKAT):
      self.assertEquals(version_codes.KITKAT, self.adb.build_version_sdk)
    self.assertEquals(version_codes.LOLLIPOP, self.adb.build_version_sdk)

  def testAssertCalls_succeeds_simple(self):
    self.assertEquals(42, self.get_answer())
    with self.assertCall(self.call.get_answer(), 123):
      self.assertEquals(123, self.get_answer())
    self.assertEquals(42, self.get_answer())

  def testAssertCalls_succeeds_multiple(self):
    with self.assertCalls(
        (mock.call.os.getcwd(), '/some/path'),
        (self.call.echo('hello'), 'hello'),
        (self.call.get_answer(), 11),
        self.call.adb.Push('this_file', 'that_file'),
        (self.call.get_answer(), 12)):
      self.assertEquals(os.getcwd(), '/some/path')
      self.assertEquals('hello', self.echo('hello'))
      self.assertEquals(11, self.get_answer())
      self.adb.Push('this_file', 'that_file')
      self.assertEquals(12, self.get_answer())

  def testAsserCalls_succeeds_withAction(self):
    with self.assertCall(
        self.call.adb.Shell('echo hello'), self.ShellError()):
      with self.assertRaises(ValueError):
        self.adb.Shell('echo hello')

  def testAssertCalls_fails_tooManyCalls(self):
    with self.assertRaises(AssertionError):
      with self.assertCalls(self.call.adb.IsOnline()):
        self.adb.IsOnline()
        self.adb.IsOnline()

  def testAssertCalls_fails_tooFewCalls(self):
    with self.assertRaises(AssertionError):
      with self.assertCalls(self.call.adb.IsOnline()):
        pass

  def testAssertCalls_succeeds_extraCalls(self):
    # we are not watching Reboot, so the assertion succeeds
    with self.assertCalls(self.call.adb.IsOnline()):
      self.adb.IsOnline()
      self.adb.Reboot()

  def testAssertCalls_fails_extraCalls(self):
    self.watchCalls([self.call.adb.Reboot])
    # this time we are also watching Reboot, so the assertion fails
    with self.assertRaises(AssertionError):
      with self.assertCalls(self.call.adb.IsOnline()):
        self.adb.IsOnline()
        self.adb.Reboot()

  def testAssertCalls_succeeds_NoCalls(self):
    self.watchMethodCalls(self.call.adb)  # we are watching all adb methods
    with self.assertCalls():
      pass

  def testAssertCalls_fails_NoCalls(self):
    self.watchMethodCalls(self.call.adb)
    with self.assertRaises(AssertionError):
      with self.assertCalls():
        self.adb.IsOnline()


if __name__ == '__main__':
  logging.getLogger().setLevel(logging.DEBUG)
  unittest.main(verbosity=2)

