blob: 3c00a0e7c9344c6b17b0aabc23aab5d3b61f94cc [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittest for cros.factory.utils.type_utils."""
import unittest
from cros.factory.utils import type_utils
# Jon's favorite character for Unicode testing: 囧
JIONG_UTF8 = '\xe5\x9b\xa7'
class FlattenListTest(unittest.TestCase):
def runTest(self):
self.assertEqual([], type_utils.FlattenList([]))
self.assertEqual([], type_utils.FlattenList([[]]))
self.assertEqual([1], type_utils.FlattenList([1]))
self.assertEqual([1], type_utils.FlattenList([1, []]))
self.assertEqual([1, 2, 3, 4, 5, 6],
type_utils.FlattenList([1, 2, [3, 4, []], 5, 6]))
class FlattenTupleTest(unittest.TestCase):
def runTest(self):
self.assertEqual((), type_utils.FlattenTuple(()))
self.assertEqual((), type_utils.FlattenTuple((())))
self.assertEqual((1, ), type_utils.FlattenTuple((1, )))
self.assertEqual((1, ), type_utils.FlattenTuple((1, ())))
self.assertEqual((1, 2, 3, 4, 5, 6),
type_utils.FlattenTuple((1, 2, (3, 4, ()), 5, 6)))
class MakeListTest(unittest.TestCase):
def runTest(self):
self.assertEqual(['a'], type_utils.MakeList('a'))
self.assertEqual(['abc'], type_utils.MakeList('abc'))
self.assertEqual(['a', 'b'], type_utils.MakeList(['a', 'b']))
self.assertEqual(['a', 'b'], type_utils.MakeList({'a': 'foo', 'b': 'bar'}))
class MakeTupleTest(unittest.TestCase):
def runTest(self):
self.assertEqual(('a',), type_utils.MakeTuple('a'))
self.assertEqual(('abc',), type_utils.MakeTuple('abc'))
self.assertEqual(('a', 'b'), type_utils.MakeTuple(['a', 'b']))
self.assertEqual(
('a', 'b'), type_utils.MakeTuple({'a': 'foo', 'b': 'bar'}))
self.assertEqual(
(1, 2, (3, 4, ('str',))),
type_utils.MakeTuple([1, 2, (3, 4, ['str'])]))
class MakeSetTest(unittest.TestCase):
def runTest(self):
self.assertEqual(set(['ab']), type_utils.MakeSet('ab'))
self.assertEqual(set(['a', 'b']), type_utils.MakeSet(['a', 'b']))
self.assertEqual(set(['a', 'b']), type_utils.MakeSet(('a', 'b')))
self.assertEqual(set(['a', 'b']),
type_utils.MakeSet({'a': 'foo', 'b': 'bar'}))
class AttrDictTest(unittest.TestCase):
def testAttrDictInit(self):
init_value = {
'key': 'value_1',
'keydict': {'key2': 'value_key2_2'},
'keylist': [0, 1, 2, {'key3': 'value_keylist_3_key3'}, 4]}
adict = type_utils.AttrDict(init_value)
self.assertEqual('value_1', adict.key)
self.assertEqual('value_key2_2', adict.keydict.key2)
self.assertEqual('value_keylist_3_key3', adict.keylist[3].key3)
def testAttrDictSetGet(self):
adict = type_utils.AttrDict()
adict['foo'] = 'bar'
self.assertEqual('bar', adict.foo)
adict.somekey = 'blah'
self.assertEqual('blah', adict['somekey'])
class LazyPropertyTest(unittest.TestCase):
class BaseClass:
def __init__(self):
self.prop_initialized = 0
@type_utils.LazyProperty
def myclass(self):
self.prop_initialized += 1
return LazyPropertyTest.BaseClass
@type_utils.LazyProperty
def base_prop(self):
return 'base_prop'
class DerivedClass(BaseClass):
@type_utils.LazyProperty
def myclass(self):
self.prop_initialized += 1
return LazyPropertyTest.DerivedClass
@type_utils.LazyProperty
def derived_prop(self):
return 'derived_prop'
def testGetterForBaseClass(self):
obj = self.BaseClass()
self.assertEqual(obj.myclass, self.BaseClass)
self.assertEqual(obj.prop_initialized, 1)
self.assertEqual(obj.myclass, self.BaseClass)
self.assertEqual(obj.prop_initialized, 1)
def testGetterForDerivedClass(self):
obj = self.DerivedClass()
self.assertEqual(obj.myclass, self.DerivedClass)
self.assertEqual(obj.prop_initialized, 1)
self.assertEqual(obj.myclass, self.DerivedClass)
self.assertEqual(obj.prop_initialized, 1)
def testSetByAssign(self):
obj = self.BaseClass()
with self.assertRaises(AttributeError):
obj.myclass = 123
obj = self.DerivedClass()
with self.assertRaises(AttributeError):
obj.myclass = 123
def testSetByOverrideOnBaseClass(self):
obj = self.BaseClass()
type_utils.LazyProperty.Override(obj, 'myclass', 123)
self.assertEqual(obj.prop_initialized, 0)
self.assertEqual(obj.myclass, 123)
type_utils.LazyProperty.Override(obj, 'base_prop', 456)
self.assertEqual(obj.base_prop, 456)
def testSetByOverrideOnDerivedClass(self):
obj = self.DerivedClass()
type_utils.LazyProperty.Override(obj, 'myclass', 123)
self.assertEqual(obj.prop_initialized, 0)
self.assertEqual(obj.myclass, 123)
type_utils.LazyProperty.Override(obj, 'base_prop', 456)
self.assertEqual(obj.base_prop, 456)
type_utils.LazyProperty.Override(obj, 'derived_prop', 789)
self.assertEqual(obj.derived_prop, 789)
class LazyObjectTest(unittest.TestCase):
class BaseClass:
def __init__(self, output):
self.x = 0
self.output = output
self.output['init'] = True
def inc(self):
self.x += 1
self.output['inc'] = True
def testLazyCreation(self):
o = {}
a = type_utils.LazyObject(self.BaseClass, o)
self.assertEqual(o.get('init'), None)
self.assertEqual(a.x, 0)
self.assertEqual(o.get('init'), True)
def testVariableMember(self):
o = {}
a = type_utils.LazyObject(self.BaseClass, o)
self.assertEqual(a.x, 0)
a.inc()
self.assertEqual(a.x, 1)
class CachedGetterTest(unittest.TestCase):
def setUp(self):
self.data = {'init': 0}
@type_utils.CachedGetter
def simple_getter():
self.data['init'] += 1
return self.data['init']
@type_utils.CachedGetter
def args_getter(v):
return v + 1
self.simple_getter = simple_getter
self.args_getter = args_getter
def testSimpleGetter(self):
self.assertEqual(self.simple_getter(), 1)
self.assertEqual(self.data['init'], 1)
self.assertEqual(self.simple_getter(), 1)
self.assertEqual(self.data['init'], 1)
self.simple_getter.InvalidateCache()
self.assertEqual(self.simple_getter(), 2)
self.assertEqual(self.data['init'], 2)
self.assertEqual(self.simple_getter(), 2)
self.assertEqual(self.data['init'], 2)
self.simple_getter.Override(3)
self.assertEqual(self.simple_getter(), 3)
self.assertEqual(self.data['init'], 2)
self.assertEqual(self.simple_getter(), 3)
self.assertEqual(self.data['init'], 2)
def testArgsGetter(self):
"""Test getter with arguments.
Currently we ignore different arguments and always return first cached
value. The goal of this unit test function is to make sure this behavior
won't change unexpectedly.
If we decide to support multiple cached values, or invalidate whenever
arguments are changed, please first make sure all users of CachedGetter
won't have problem and then change this unit test.
"""
self.assertEqual(self.args_getter(0), 1)
self.assertEqual(self.args_getter(1), 1)
self.assertEqual(self.args_getter(2), 1)
self.args_getter.InvalidateCache()
self.assertEqual(self.args_getter(2), 3)
self.assertEqual(self.args_getter(1), 3)
self.assertEqual(self.args_getter(0), 3)
class UniqueSetTest(unittest.TestCase):
def setUp(self):
self.container = type_utils.UniqueStack()
def testInsertThenGet(self):
for x in [5, 1, 2, 4, 3]:
self.container.Add(x)
self.assertEqual(self.container.Get(), x)
def testDeleteOlderObject(self):
data = [5, 1, 2, 4, 3]
for x in data:
self.container.Add(x)
last = data.pop()
self.assertEqual(self.container.Get(), last)
for x in data:
self.container.Del(x)
self.assertEqual(self.container.Get(), last)
def testInsertExistingObject(self):
data = [5, 4, 3, 2, 1, 0]
for x in data:
self.container.Add(x)
for x in data:
self.container.Add(x)
self.assertEqual(self.container.Get(), 0)
def testGetAfterDelete(self):
for x in range(5):
self.container.Add(x)
for x in range(4, 0, -1):
self.container.Del(x)
self.assertEqual(self.container.Get(), x - 1)
def testInsertAfterDelete(self):
self.container.Add(1)
self.container.Add(2)
self.container.Del(1)
self.assertEqual(self.container.Get(), 2)
self.container.Add(1)
self.assertEqual(self.container.Get(), 1)
class GetDictTest(unittest.TestCase):
def testGet(self):
GetDict = type_utils.GetDict
data = {
'blah': 1,
'services': {
'shop_floor': {
}
}
}
self.assertEqual(GetDict(data, 'blah'), 1)
self.assertEqual(GetDict(data, 'non_exist'), None)
self.assertEqual(GetDict(data, 'non_exist', True), True)
self.assertEqual(GetDict(data, 'services.non_exist', 'N/A'), 'N/A')
self.assertEqual(GetDict(data, 'services.shop_floor', 'FAIL'), {})
self.assertEqual(GetDict(
data, 'services.shop_floor.service_url', 'DEFAULT'), 'DEFAULT')
class BindFunctionTest(unittest.TestCase):
def runTest(self):
def func(a, b):
"""Adds two numbers."""
return a + b
bound_func = type_utils.BindFunction(func, 123, 151)
self.assertEqual(274, bound_func())
self.assertEqual(274, bound_func())
self.assertEqual('func', bound_func.__name__)
self.assertEqual('Adds two numbers.', bound_func.__doc__)
if __name__ == "__main__":
unittest.main()