blob: 5845811867c40d57046363c495cbe221b32f1a87 [file] [log] [blame]
#!/usr/bin/env python
# coding=utf-8
# Copyright [2017] [B2W Digital]
#
# 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.
import uuid
import datetime
import json
import pytest
try:
import mock
except ImportError:
import unittest.mock as mock
from marvin_python_toolbox.common.utils import (class_property, memoized_class_property, get_datetime, deprecated,
to_json, from_json, is_valid_json, validate_json, generate_key, to_slug,
url_encode, getattr_qualified, chunks, check_path)
from marvin_python_toolbox.common.exceptions import InvalidJsonException
instance_count = 0
# ==============================================================================
# Test memoized_class_property
class Dummy:
@memoized_class_property
def my_cls_attribute(cls):
global instance_count
instance_count += 1
return 42
@class_property
def my_cls_property(cls):
return 'oi'
def any_method(self):
return self.my_cls_attribute
def test_initial_instance_count():
global instance_count
assert 0 == instance_count
def test_property():
assert 42 == Dummy.my_cls_attribute
def test_access_from_instance_method():
assert 42 == Dummy().any_method()
def test_create_only_one_instance():
global instance_count
Dummy.my_cls_attribute
assert 1 == instance_count
Dummy.my_cls_attribute
assert 1 == instance_count
def test_class_property():
assert Dummy.my_cls_property == 'oi'
# ==============================================================================
# test to_json & from_json
def test_to_json():
d = {'i': 42, 's': 'string', 'dt': datetime.datetime.now(), 'id': uuid.uuid4()}
assert isinstance(to_json(d), str)
def test_to_json_with_obj_with_id():
class Obj(object):
id = '42'
d = {'i': Obj()}
assert isinstance(to_json(d), str)
def test_to_json_with_obj_without_id():
class Obj(object):
pass
d = {'i': Obj()}
with pytest.raises(TypeError):
to_json(d)
def test_to_json_with_numpy():
class FakeNumpyFloat(object):
def item(self):
return 0.666
d = {'float': FakeNumpyFloat()}
assert to_json(d) == '{"float": 0.666}'
def test_from_json():
d = {'i': 42, 's': 'string', 'dt': datetime.datetime.now(), 'id': uuid.uuid4()}
assert isinstance(from_json(to_json(d)), dict)
def test_validate_json():
valid = {
'prop': ['a', 'b' , 'c']
}
invalid = {
'prop': 'a'
}
schema = {
'type': 'object',
'properties': {
'prop': {
'type': 'array',
'items': { 'type': 'string' }
}
}
}
validate_json(valid, schema=schema)
with pytest.raises(InvalidJsonException):
validate_json(invalid, schema=schema)
def test_is_valid_json():
valid = {
'prop': ['a', 'b' , 'c']
}
invalid = {
'prop': 'a'
}
schema = {
'type': 'object',
'properties': {
'prop': {
'type': 'array',
'items': { 'type': 'string' }
}
}
}
assert is_valid_json(valid, schema=schema) is True
assert is_valid_json(invalid, schema=schema) is False
assert is_valid_json(json.dumps(valid), schema=json.dumps(schema)) is True
assert is_valid_json(json.dumps(invalid), schema=json.dumps(schema)) is False
def test_generate_key():
value = 'www.image.com.br'
valid_sha256 = '58643ebba1abbbd92c586957a98c9f3e8a104b681eb37b99df50b2e1044bbf20'
assert generate_key(value) == valid_sha256
def test_generate_key_with_unicode():
value = u'http://static.wmobjects.com.br/imgres/arquivos/ids/2509201-344-344/torradeira-cuisinart-tan-4-\u2013-branca.jpg'
assert generate_key(value)
def test_to_slug():
assert to_slug('any text') == "any-text"
def test_chunk():
assert len(list(chunks([1, 2, 3, 4], 2))) == 2
def test_getattr_qualified():
class B(object):
c = {'d': 'e'}
class A(object):
b = B()
a = A()
assert getattr_qualified(a, 'b') == a.b
assert getattr_qualified(a, 'b.c') == a.b.c
assert getattr_qualified(a, 'b.c["d"]') == a.b.c['d']
assert getattr_qualified(a, "b.c['d']") == a.b.c['d']
assert getattr_qualified(a, "b.c[d]") == a.b.c['d']
assert getattr_qualified(a, "b.c[f]", 'default') == 'default'
assert getattr_qualified(a, "x.c[f]", 'default') == 'default'
with pytest.raises(AttributeError):
getattr_qualified(a, 'x.c[f]')
with pytest.raises(KeyError):
getattr_qualified(a, 'b.c["z"]')
with pytest.raises(TypeError):
getattr_qualified(a, 'b', 'default', 'bla')
@mock.patch('marvin_python_toolbox.common.utils.os.path.exists')
def test_path_not_exists(path_exists_mock):
path_exists_mock.return_value = False
assert not check_path('temp')
@mock.patch('marvin_python_toolbox.common.utils.os.makedirs')
@mock.patch('marvin_python_toolbox.common.utils.os.path.exists')
def test_path_creation(path_exists_mock, makedirs_mock):
path_exists_mock.side_effect = [False, True]
makedirs_mock.return_value = None
assert check_path('temp', create=True)
def test_get_datetime():
date = get_datetime()
date = date.split()
assert len(date[0]) == 10
assert len(date[1]) == 8
assert date[2] == 'UTC'
def test_deprecated():
@deprecated
def deprecated_func():
pass
with pytest.warns(DeprecationWarning):
deprecated_func()
def test_url_encode():
original = u'http://host.com/path_with_special_char_áéíóú?and=query&string=true'
transformed = 'http://host.com/path_with_special_char_%C3%A1%C3%A9%C3%AD%C3%B3%C3%BA?and=query&string=true'
assert url_encode(original) == transformed
def test_url_encode_string():
original = b'http://host.com/path_with_special_char_\xc3\xa1\xc3\xa9\xc3\xad\xc3\xb3\xc3\xba?and=query&string=true'
transformed = 'http://host.com/path_with_special_char_%C3%A1%C3%A9%C3%AD%C3%B3%C3%BA?and=query&string=true'
assert url_encode(original) == transformed