blob: 14e7f7ebf67f5a29931d149f382087fb1f029b6e [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright 2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Tests for apitools.base.protorpclite.util."""
import datetime
import sys
import types
import unittest
import six
from apitools.base.protorpclite import test_util
from apitools.base.protorpclite import util
class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
test_util.TestCase):
MODULE = util
class UtilTest(test_util.TestCase):
def testDecoratedFunction_LengthZero(self):
@util.positional(0)
def fn(kwonly=1):
return [kwonly]
self.assertEquals([1], fn())
self.assertEquals([2], fn(kwonly=2))
self.assertRaisesWithRegexpMatch(TypeError,
r'fn\(\) takes at most 0 positional '
r'arguments \(1 given\)',
fn, 1)
def testDecoratedFunction_LengthOne(self):
@util.positional(1)
def fn(pos, kwonly=1):
return [pos, kwonly]
self.assertEquals([1, 1], fn(1))
self.assertEquals([2, 2], fn(2, kwonly=2))
self.assertRaisesWithRegexpMatch(TypeError,
r'fn\(\) takes at most 1 positional '
r'argument \(2 given\)',
fn, 2, 3)
def testDecoratedFunction_LengthTwoWithDefault(self):
@util.positional(2)
def fn(pos1, pos2=1, kwonly=1):
return [pos1, pos2, kwonly]
self.assertEquals([1, 1, 1], fn(1))
self.assertEquals([2, 2, 1], fn(2, 2))
self.assertEquals([2, 3, 4], fn(2, 3, kwonly=4))
self.assertRaisesWithRegexpMatch(TypeError,
r'fn\(\) takes at most 2 positional '
r'arguments \(3 given\)',
fn, 2, 3, 4)
def testDecoratedMethod(self):
class MyClass(object):
@util.positional(2)
def meth(self, pos1, kwonly=1):
return [pos1, kwonly]
self.assertEquals([1, 1], MyClass().meth(1))
self.assertEquals([2, 2], MyClass().meth(2, kwonly=2))
self.assertRaisesWithRegexpMatch(
TypeError,
r'meth\(\) takes at most 2 positional arguments \(3 given\)',
MyClass().meth, 2, 3)
def testDefaultDecoration(self):
@util.positional
def fn(a, b, c=None):
return a, b, c
self.assertEquals((1, 2, 3), fn(1, 2, c=3))
self.assertEquals((3, 4, None), fn(3, b=4))
self.assertRaisesWithRegexpMatch(TypeError,
r'fn\(\) takes at most 2 positional '
r'arguments \(3 given\)',
fn, 2, 3, 4)
def testDefaultDecorationNoKwdsFails(self):
def fn(a):
return a
self.assertRaisesRegexp(
ValueError,
('Functions with no keyword arguments must specify '
'max_positional_args'),
util.positional, fn)
def testDecoratedFunctionDocstring(self):
@util.positional(0)
def fn(kwonly=1):
"""fn docstring."""
return [kwonly]
self.assertEquals('fn docstring.', fn.__doc__)
class GetPackageForModuleTest(test_util.TestCase):
def setUp(self):
self.original_modules = dict(sys.modules)
def tearDown(self):
sys.modules.clear()
sys.modules.update(self.original_modules)
def CreateModule(self, name, file_name=None):
if file_name is None:
file_name = '%s.py' % name
module = types.ModuleType(name)
sys.modules[name] = module
return module
def assertPackageEquals(self, expected, actual):
self.assertEquals(expected, actual)
if actual is not None:
self.assertTrue(isinstance(actual, six.text_type))
def testByString(self):
module = self.CreateModule('service_module')
module.package = 'my_package'
self.assertPackageEquals('my_package',
util.get_package_for_module('service_module'))
def testModuleNameNotInSys(self):
self.assertPackageEquals(None,
util.get_package_for_module('service_module'))
def testHasPackage(self):
module = self.CreateModule('service_module')
module.package = 'my_package'
self.assertPackageEquals(
'my_package', util.get_package_for_module(module))
def testHasModuleName(self):
module = self.CreateModule('service_module')
self.assertPackageEquals('service_module',
util.get_package_for_module(module))
def testIsMain(self):
module = self.CreateModule('__main__')
module.__file__ = '/bing/blam/bloom/blarm/my_file.py'
self.assertPackageEquals(
'my_file', util.get_package_for_module(module))
def testIsMainCompiled(self):
module = self.CreateModule('__main__')
module.__file__ = '/bing/blam/bloom/blarm/my_file.pyc'
self.assertPackageEquals(
'my_file', util.get_package_for_module(module))
def testNoExtension(self):
module = self.CreateModule('__main__')
module.__file__ = '/bing/blam/bloom/blarm/my_file'
self.assertPackageEquals(
'my_file', util.get_package_for_module(module))
def testNoPackageAtAll(self):
module = self.CreateModule('__main__')
self.assertPackageEquals(
'__main__', util.get_package_for_module(module))
class DateTimeTests(test_util.TestCase):
def testDecodeDateTime(self):
"""Test that a RFC 3339 datetime string is decoded properly."""
for datetime_string, datetime_vals in (
('2012-09-30T15:31:50.262', (2012, 9, 30, 15, 31, 50, 262000)),
('2012-09-30T15:31:50', (2012, 9, 30, 15, 31, 50, 0))):
decoded = util.decode_datetime(datetime_string)
expected = datetime.datetime(*datetime_vals)
self.assertEquals(expected, decoded)
def testDateTimeTimeZones(self):
"""Test that a datetime string with a timezone is decoded correctly."""
tests = (
('2012-09-30T15:31:50.262-06:00',
(2012, 9, 30, 15, 31, 50, 262000, util.TimeZoneOffset(-360))),
('2012-09-30T15:31:50.262+01:30',
(2012, 9, 30, 15, 31, 50, 262000, util.TimeZoneOffset(90))),
('2012-09-30T15:31:50+00:05',
(2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(5))),
('2012-09-30T15:31:50+00:00',
(2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))),
('2012-09-30t15:31:50-00:00',
(2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))),
('2012-09-30t15:31:50z',
(2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(0))),
('2012-09-30T15:31:50-23:00',
(2012, 9, 30, 15, 31, 50, 0, util.TimeZoneOffset(-1380))))
for datetime_string, datetime_vals in tests:
decoded = util.decode_datetime(datetime_string)
expected = datetime.datetime(*datetime_vals)
self.assertEquals(expected, decoded)
def testDecodeDateTimeInvalid(self):
"""Test that decoding malformed datetime strings raises execptions."""
for datetime_string in ('invalid',
'2012-09-30T15:31:50.',
'-08:00 2012-09-30T15:31:50.262',
'2012-09-30T15:31',
'2012-09-30T15:31Z',
'2012-09-30T15:31:50ZZ',
'2012-09-30T15:31:50.262 blah blah -08:00',
'1000-99-99T25:99:99.999-99:99'):
self.assertRaises(
ValueError, util.decode_datetime, datetime_string)
def testTimeZoneOffsetDelta(self):
"""Test that delta works with TimeZoneOffset."""
time_zone = util.TimeZoneOffset(datetime.timedelta(minutes=3))
epoch = time_zone.utcoffset(datetime.datetime.utcfromtimestamp(0))
self.assertEqual(180, util.total_seconds(epoch))
def main():
unittest.main()
if __name__ == '__main__':
main()