#!/usr/bin/env vpython
# Copyright 2015 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.

import copy

import test_env

from recipe_engine import util


class TestMultiException(test_env.RecipeEngineUnitTest):

  def testNoExceptionsRaisesNothing(self):
    mb = util.MultiException.Builder()
    with mb.catch():
      pass
    mb.raise_if_any()

    mexc = util.MultiException()
    self.assertEqual(str(mexc), 'MultiException(No exceptions)')

  def testExceptionsRaised(self):
    fail_exc = Exception('fail!')
    mb = util.MultiException.Builder()
    with mb.catch():
      raise fail_exc

    mexc = mb.get()
    self.assertEqual(len(mexc), 1)
    self.assertIs(mexc[0], fail_exc)
    self.assertEqual(str(mexc), 'MultiException(fail!)')

  def testMultipleExceptions(self):
    mb = util.MultiException.Builder()
    with mb.catch():
      raise KeyError('One')
    with mb.catch():
      raise ValueError('Two')

    mexc = mb.get()
    self.assertIsNotNone(mexc)
    self.assertEqual(len(mexc), 2)

    exceptions = list(mexc)
    self.assertIsInstance(exceptions[0], KeyError)
    self.assertIsInstance(exceptions[1], ValueError)
    self.assertEqual(str(mexc), "MultiException('One', and 1 more...)")

  def testTargetedException(self):
    mb = util.MultiException().Builder()
    def not_caught():
      with mb.catch(ValueError):
        raise KeyError('One')
    self.assertRaises(KeyError, not_caught)
    self.assertIsNone(mb.get())


class TestMapDeferExceptions(test_env.RecipeEngineUnitTest):

  def testNoExceptionsDoesNothing(self):
    v = []
    util.map_defer_exceptions(lambda e: v.append(e), [1, 2, 3])
    self.assertEqual(v, [1, 2, 3])

  def testCatchesExceptions(self):
    v = []
    def fn(e):
      if e == 0:
        raise ValueError('Zero')
      v.append(e)

    mexc = None
    try:
      util.map_defer_exceptions(fn, [0, 1, 0, 0, 2, 0, 3, 0])
    except util.MultiException as e:
      mexc = e

    self.assertEqual(v, [1, 2, 3])
    self.assertIsNotNone(mexc)
    self.assertEqual(len(mexc), 5)

  def testCatchesSpecificExceptions(self):
    def fn(e):
      raise ValueError('Zero')
    self.assertRaises(ValueError, util.map_defer_exceptions, fn, [1], KeyError)

class TestSentinel(test_env.RecipeEngineUnitTest):
  SENTINEL = util.sentinel('SENTINEL')

  def test_repr(self):
    self.assertEqual(repr(self.SENTINEL), 'SENTINEL')

  def test_copy(self):
    self.assertIs(copy.copy(self.SENTINEL), self.SENTINEL)

  def test_deepcopy(self):
    self.assertIs(copy.deepcopy(self.SENTINEL), self.SENTINEL)


if __name__ == '__main__':
  test_env.main()
