You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gallery-dl/test/test_util.py

838 lines
28 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2015-2023 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
import os
import sys
import unittest
import io
import time
import random
import string
import datetime
import platform
import tempfile
import itertools
import http.cookiejar
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from gallery_dl import util, text, exception # noqa E402
class TestRange(unittest.TestCase):
def test_parse_empty(self, f=util.RangePredicate._parse):
self.assertEqual(f(""), [])
self.assertEqual(f([]), [])
def test_parse_digit(self, f=util.RangePredicate._parse):
self.assertEqual(f("2"), [range(2, 3)])
self.assertEqual(
f("2, 3, 4"),
[range(2, 3),
range(3, 4),
range(4, 5)],
)
def test_parse_range(self, f=util.RangePredicate._parse):
self.assertEqual(f("1-2"), [range(1, 3)])
self.assertEqual(f("2-"), [range(2, sys.maxsize)])
self.assertEqual(f("-3"), [range(1, 4)])
self.assertEqual(f("-"), [range(1, sys.maxsize)])
self.assertEqual(
f("-2,4,6-8,10-"),
[range(1, 3),
range(4, 5),
range(6, 9),
range(10, sys.maxsize)],
)
self.assertEqual(
f(" - 3 , 4- 4, 2-6"),
[range(1, 4),
range(4, 5),
range(2, 7)],
)
def test_parse_slice(self, f=util.RangePredicate._parse):
self.assertEqual(f("2:4") , [range(2, 4)])
self.assertEqual(f("3::") , [range(3, sys.maxsize)])
self.assertEqual(f(":4:") , [range(1, 4)])
self.assertEqual(f("::5") , [range(1, sys.maxsize, 5)])
self.assertEqual(f("::") , [range(1, sys.maxsize)])
self.assertEqual(f("2:3:4"), [range(2, 3, 4)])
self.assertEqual(
f("2:4, 4:, :4, :4:, ::4"),
[range(2, 4),
range(4, sys.maxsize),
range(1, 4),
range(1, 4),
range(1, sys.maxsize, 4)],
)
self.assertEqual(
f(" : 3 , 4: 4, 2:6"),
[range(1, 3),
range(4, 4),
range(2, 6)],
)
class TestPredicate(unittest.TestCase):
def test_range_predicate(self):
dummy = None
pred = util.RangePredicate(" - 3 , 4- 4, 2-6")
for i in range(6):
self.assertTrue(pred(dummy, dummy))
with self.assertRaises(exception.StopExtraction):
pred(dummy, dummy)
pred = util.RangePredicate("1, 3, 5")
self.assertTrue(pred(dummy, dummy))
self.assertFalse(pred(dummy, dummy))
self.assertTrue(pred(dummy, dummy))
self.assertFalse(pred(dummy, dummy))
self.assertTrue(pred(dummy, dummy))
with self.assertRaises(exception.StopExtraction):
pred(dummy, dummy)
pred = util.RangePredicate("")
with self.assertRaises(exception.StopExtraction):
pred(dummy, dummy)
def test_unique_predicate(self):
dummy = None
pred = util.UniquePredicate()
# no duplicates
self.assertTrue(pred("1", dummy))
self.assertTrue(pred("2", dummy))
self.assertFalse(pred("1", dummy))
self.assertFalse(pred("2", dummy))
self.assertTrue(pred("3", dummy))
self.assertFalse(pred("3", dummy))
# duplicates for "text:"
self.assertTrue(pred("text:123", dummy))
self.assertTrue(pred("text:123", dummy))
self.assertTrue(pred("text:123", dummy))
def test_filter_predicate(self):
url = ""
pred = util.FilterPredicate("a < 3")
self.assertTrue(pred(url, {"a": 2}))
self.assertFalse(pred(url, {"a": 3}))
with self.assertRaises(SyntaxError):
util.FilterPredicate("(")
self.assertFalse(
util.FilterPredicate("a > 1")(url, {"a": None}))
self.assertFalse(
util.FilterPredicate("b > 1")(url, {"a": 2}))
pred = util.FilterPredicate(["a < 3", "b < 4", "c < 5"])
self.assertTrue(pred(url, {"a": 2, "b": 3, "c": 4}))
self.assertFalse(pred(url, {"a": 3, "b": 3, "c": 4}))
self.assertFalse(pred(url, {"a": 2, "b": 4, "c": 4}))
self.assertFalse(pred(url, {"a": 2, "b": 3, "c": 5}))
self.assertFalse(pred(url, {"a": 2}))
def test_build_predicate(self):
pred = util.build_predicate([])
self.assertIsInstance(pred, type(lambda: True))
pred = util.build_predicate([util.UniquePredicate()])
self.assertIsInstance(pred, util.UniquePredicate)
pred = util.build_predicate([util.UniquePredicate(),
util.UniquePredicate()])
self.assertIs(pred.func, util.chain_predicates)
class TestISO639_1(unittest.TestCase):
def test_code_to_language(self):
d = "default"
self._run_test(util.code_to_language, {
("en",): "English",
("FR",): "French",
("ja",): "Japanese",
("xx",): None,
("" ,): None,
(None,): None,
("en", d): "English",
("FR", d): "French",
("xx", d): d,
("" , d): d,
(None, d): d,
})
def test_language_to_code(self):
d = "default"
self._run_test(util.language_to_code, {
("English",): "en",
("fRENch",): "fr",
("Japanese",): "ja",
("xx",): None,
("" ,): None,
(None,): None,
("English", d): "en",
("fRENch", d): "fr",
("xx", d): d,
("" , d): d,
(None, d): d,
})
def _run_test(self, func, tests):
for args, result in tests.items():
self.assertEqual(func(*args), result)
class TestCookiesTxt(unittest.TestCase):
def test_cookiestxt_load(self):
def _assert(content, expected):
jar = http.cookiejar.CookieJar()
util.cookiestxt_load(io.StringIO(content, None), jar)
for c, e in zip(jar, expected):
self.assertEqual(c.__dict__, e.__dict__)
_assert("", [])
_assert("\n\n\n", [])
_assert("$ Comment", [])
_assert("# Comment", [])
_assert(" # Comment \n\n $ Comment ", [])
_assert(
".example.org\tTRUE\t/\tTRUE\t0\tname\tvalue",
[self._cookie("name", "value", ".example.org")],
)
_assert(
".example.org\tTRUE\t/\tTRUE\t\tname\t",
[self._cookie("name", "", ".example.org")],
)
_assert(
"\tTRUE\t/\tTRUE\t\tname\t",
[self._cookie("name", "", "")],
)
_assert(
"# Netscape HTTP Cookie File\n"
"\n"
"# default\n"
".example.org TRUE / FALSE 0 n1 v1\n"
".example.org TRUE / TRUE 2145945600 n2 v2\n"
".example.org TRUE /path FALSE 0 n3\n"
"\n"
" # # extra # # \n"
"www.example.org FALSE / FALSE n4 \n"
"www.example.org FALSE /path FALSE 100 n5 v5\n",
[
self._cookie(
"n1", "v1", ".example.org", True, "/", False),
self._cookie(
"n2", "v2", ".example.org", True, "/", True, 2145945600),
self._cookie(
"n3", None, ".example.org", True, "/path", False),
self._cookie(
"n4", "" , "www.example.org", False, "/", False),
self._cookie(
"n5", "v5", "www.example.org", False, "/path", False, 100),
],
)
with self.assertRaises(ValueError):
util.cookiestxt_load("example.org\tTRUE\t/\tTRUE\t0\tname",
http.cookiejar.CookieJar())
def test_cookiestxt_store(self):
def _assert(cookies, expected):
fp = io.StringIO(newline=None)
util.cookiestxt_store(fp, cookies)
self.assertMultiLineEqual(fp.getvalue(), expected)
_assert([], "# Netscape HTTP Cookie File\n\n")
_assert(
[self._cookie("name", "value", ".example.org")],
"# Netscape HTTP Cookie File\n\n"
".example.org\tTRUE\t/\tTRUE\t0\tname\tvalue\n",
)
_assert(
[
self._cookie(
"n1", "v1", ".example.org", True, "/", False),
self._cookie(
"n2", "v2", ".example.org", True, "/", True, 2145945600),
self._cookie(
"n3", None, ".example.org", True, "/path", False),
self._cookie(
"n4", "" , "www.example.org", False, "/", False),
self._cookie(
"n5", "v5", "www.example.org", False, "/path", False, 100),
self._cookie(
"n6", "v6", "", False),
],
"# Netscape HTTP Cookie File\n"
"\n"
".example.org TRUE / FALSE 0 n1 v1\n"
".example.org TRUE / TRUE 2145945600 n2 v2\n"
".example.org TRUE /path FALSE 0 n3\n"
"www.example.org FALSE / FALSE 0 n4 \n"
"www.example.org FALSE /path FALSE 100 n5 v5\n",
)
def _cookie(self, name, value, domain, domain_specified=True,
path="/", secure=True, expires=None):
return http.cookiejar.Cookie(
0, name, value, None, False,
domain, domain_specified, domain.startswith("."),
path, False, secure, expires, False, None, None, {},
)
class TestOther(unittest.TestCase):
def test_bencode(self):
self.assertEqual(util.bencode(0), "")
self.assertEqual(util.bencode(123), "123")
self.assertEqual(util.bencode(123, "01"), "1111011")
self.assertEqual(util.bencode(123, "BA"), "AAAABAA")
def test_bdecode(self):
self.assertEqual(util.bdecode(""), 0)
self.assertEqual(util.bdecode("123"), 123)
self.assertEqual(util.bdecode("1111011", "01"), 123)
self.assertEqual(util.bdecode("AAAABAA", "BA"), 123)
def test_bencode_bdecode(self):
for _ in range(100):
value = random.randint(0, 1000000)
for alphabet in ("01", "0123456789", string.ascii_letters):
result = util.bdecode(util.bencode(value, alphabet), alphabet)
self.assertEqual(result, value)
def test_advance(self):
items = range(5)
self.assertCountEqual(
util.advance(items, 0), items)
self.assertCountEqual(
util.advance(items, 3), range(3, 5))
self.assertCountEqual(
util.advance(items, 9), [])
self.assertCountEqual(
util.advance(util.advance(items, 1), 2), range(3, 5))
def test_unique(self):
self.assertSequenceEqual(
list(util.unique("")), "")
self.assertSequenceEqual(
list(util.unique("AABBCC")), "ABC")
self.assertSequenceEqual(
list(util.unique("ABABABCAABBCC")), "ABC")
self.assertSequenceEqual(
list(util.unique([1, 2, 1, 3, 2, 1])), [1, 2, 3])
def test_unique_sequence(self):
self.assertSequenceEqual(
list(util.unique_sequence("")), "")
self.assertSequenceEqual(
list(util.unique_sequence("AABBCC")), "ABC")
self.assertSequenceEqual(
list(util.unique_sequence("ABABABCAABBCC")), "ABABABCABC")
self.assertSequenceEqual(
list(util.unique_sequence([1, 2, 1, 3, 2, 1])), [1, 2, 1, 3, 2, 1])
def test_contains(self):
c = [1, "2", 3, 4, "5", "foo"]
self.assertTrue(util.contains(c, 1))
self.assertTrue(util.contains(c, "foo"))
self.assertTrue(util.contains(c, [1, 3, "5"]))
self.assertTrue(util.contains(c, ["a", "b", "5"]))
self.assertFalse(util.contains(c, "bar"))
self.assertFalse(util.contains(c, [2, 5, "bar"]))
s = "1 2 3 asd qwe y(+)c f(+)(-) bar"
self.assertTrue(util.contains(s, "y(+)c"))
self.assertTrue(util.contains(s, ["asd", "qwe", "yxc"]))
self.assertTrue(util.contains(s, ["sdf", "dfg", "qwe"]))
self.assertFalse(util.contains(s, "tag1"))
self.assertFalse(util.contains(s, ["tag1", "tag2", "tag3"]))
s = "1, 2, 3, asd, qwe, y(+)c, f(+)(-), bar"
self.assertTrue(util.contains(s, "y(+)c", ", "))
self.assertTrue(util.contains(s, ["sdf", "dfg", "qwe"], ", "))
self.assertFalse(util.contains(s, "tag1", ", "))
def test_raises(self):
func = util.raises(Exception)
with self.assertRaises(Exception):
func()
func = util.raises(ValueError)
with self.assertRaises(ValueError):
func(1)
with self.assertRaises(ValueError):
func(2)
with self.assertRaises(ValueError):
func(3)
def test_identity(self):
for value in (123, "foo", [1, 2, 3], (1, 2, 3), {1: 2}, None):
self.assertIs(util.identity(value), value)
def test_noop(self):
self.assertEqual(util.noop(), None)
def test_md5(self):
self.assertEqual(util.md5(b""),
"d41d8cd98f00b204e9800998ecf8427e")
self.assertEqual(util.md5(b"hello"),
"5d41402abc4b2a76b9719d911017c592")
self.assertEqual(util.md5(""),
"d41d8cd98f00b204e9800998ecf8427e")
self.assertEqual(util.md5("hello"),
"5d41402abc4b2a76b9719d911017c592")
self.assertEqual(util.md5("ワルド"),
"051f29cd6c942cf110a0ccc5729871d2")
self.assertEqual(util.md5(0),
"d41d8cd98f00b204e9800998ecf8427e")
self.assertEqual(util.md5(()),
"d41d8cd98f00b204e9800998ecf8427e")
self.assertEqual(util.md5(None),
"d41d8cd98f00b204e9800998ecf8427e")
def test_sha1(self):
self.assertEqual(util.sha1(b""),
"da39a3ee5e6b4b0d3255bfef95601890afd80709")
self.assertEqual(util.sha1(b"hello"),
"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d")
self.assertEqual(util.sha1(""),
"da39a3ee5e6b4b0d3255bfef95601890afd80709")
self.assertEqual(util.sha1("hello"),
"aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d")
self.assertEqual(util.sha1("ワルド"),
"0cbe319081aa0e9298448ec2bb16df8c494aa04e")
self.assertEqual(util.sha1(0),
"da39a3ee5e6b4b0d3255bfef95601890afd80709")
self.assertEqual(util.sha1(()),
"da39a3ee5e6b4b0d3255bfef95601890afd80709")
self.assertEqual(util.sha1(None),
"da39a3ee5e6b4b0d3255bfef95601890afd80709")
def test_compile_expression(self):
expr = util.compile_expression("1 + 2 * 3")
self.assertEqual(expr(), 7)
self.assertEqual(expr({"a": 1, "b": 2, "c": 3}), 7)
self.assertEqual(expr({"a": 9, "b": 9, "c": 9}), 7)
expr = util.compile_expression("a + b * c")
self.assertEqual(expr({"a": 1, "b": 2, "c": 3}), 7)
self.assertEqual(expr({"a": 9, "b": 9, "c": 9}), 90)
expr = util.compile_expression_raw("a + b * c")
with self.assertRaises(NameError):
expr()
with self.assertRaises(NameError):
expr({"a": 2})
with self.assertRaises(SyntaxError):
util.compile_expression("")
with self.assertRaises(SyntaxError):
util.compile_expression("x++")
expr = util.compile_expression("1 and abort()")
with self.assertRaises(exception.StopExtraction):
expr()
def test_import_file(self):
module = util.import_file("datetime")
self.assertIs(module, datetime)
with tempfile.TemporaryDirectory() as path:
file = path + "/module_test.py"
with open(file, "w") as fp:
fp.write("""
import datetime
key = "foobar"
value = 123
""")
module = util.import_file(file)
self.assertEqual(module.__name__, "module_test")
self.assertEqual(module.key, "foobar")
self.assertEqual(module.value, 123)
self.assertIs(module.datetime, datetime)
def test_custom_globals(self):
value = {"v": "foobar"}
result = "8843d7f92416211de9ebb963ff4ce28125932878"
expr = util.compile_expression("hash_sha1(v)")
self.assertEqual(expr(value), result)
expr = util.compile_expression("hs(v)", globals={"hs": util.sha1})
self.assertEqual(expr(value), result)
with tempfile.TemporaryDirectory() as path:
file = path + "/module_sha1.py"
with open(file, "w") as fp:
fp.write("""
import hashlib
def hash(value):
return hashlib.sha1(value.encode()).hexdigest()
""")
module = util.import_file(file)
expr = util.compile_expression("hash(v)", globals=module.__dict__)
self.assertEqual(expr(value), result)
GLOBALS_ORIG = util.GLOBALS
try:
util.GLOBALS = module.__dict__
expr = util.compile_expression("hash(v)")
finally:
util.GLOBALS = GLOBALS_ORIG
self.assertEqual(expr(value), result)
def test_build_duration_func(self, f=util.build_duration_func):
def test_single(df, v):
for _ in range(10):
self.assertEqual(df(), v)
def test_range(df, lower, upper):
for __ in range(10):
v = df()
self.assertGreaterEqual(v, lower)
self.assertLessEqual(v, upper)
for v in (0, 0.0, "", None, (), []):
self.assertIsNone(f(v))
for v in (0, 0.0, "", None, (), []):
test_single(f(v, 1.0), 1.0)
test_single(f(3), 3)
test_single(f(3.0), 3.0)
test_single(f("3"), 3)
test_single(f("3.0-"), 3)
test_single(f(" 3 -"), 3)
test_range(f((2, 4)), 2, 4)
test_range(f([2, 4]), 2, 4)
test_range(f("2-4"), 2, 4)
test_range(f(" 2.0 - 4 "), 2, 4)
def test_extractor_filter(self):
# empty
func = util.build_extractor_filter("")
self.assertEqual(func(TestExtractor) , True)
self.assertEqual(func(TestExtractorParent), True)
self.assertEqual(func(TestExtractorAlt) , True)
# category
func = util.build_extractor_filter("test_category")
self.assertEqual(func(TestExtractor) , False)
self.assertEqual(func(TestExtractorParent), False)
self.assertEqual(func(TestExtractorAlt) , True)
# subcategory
func = util.build_extractor_filter("*:test_subcategory")
self.assertEqual(func(TestExtractor) , False)
self.assertEqual(func(TestExtractorParent), True)
self.assertEqual(func(TestExtractorAlt) , False)
# basecategory
func = util.build_extractor_filter("test_basecategory")
self.assertEqual(func(TestExtractor) , False)
self.assertEqual(func(TestExtractorParent), False)
self.assertEqual(func(TestExtractorAlt) , False)
# category-subcategory pair
func = util.build_extractor_filter("test_category:test_subcategory")
self.assertEqual(func(TestExtractor) , False)
self.assertEqual(func(TestExtractorParent), True)
self.assertEqual(func(TestExtractorAlt) , True)
# combination
func = util.build_extractor_filter(
["test_category", "*:test_subcategory"])
self.assertEqual(func(TestExtractor) , False)
self.assertEqual(func(TestExtractorParent), False)
self.assertEqual(func(TestExtractorAlt) , False)
# whitelist
func = util.build_extractor_filter(
"test_category:test_subcategory", negate=False)
self.assertEqual(func(TestExtractor) , True)
self.assertEqual(func(TestExtractorParent), False)
self.assertEqual(func(TestExtractorAlt) , False)
func = util.build_extractor_filter(
["test_category:test_subcategory", "*:test_subcategory_parent"],
negate=False)
self.assertEqual(func(TestExtractor) , True)
self.assertEqual(func(TestExtractorParent), True)
self.assertEqual(func(TestExtractorAlt) , False)
def test_generate_token(self):
tokens = set()
for _ in range(100):
token = util.generate_token()
tokens.add(token)
self.assertEqual(len(token), 16 * 2)
self.assertRegex(token, r"^[0-9a-f]+$")
self.assertGreaterEqual(len(tokens), 99)
token = util.generate_token(80)
self.assertEqual(len(token), 80 * 2)
self.assertRegex(token, r"^[0-9a-f]+$")
def test_format_value(self):
self.assertEqual(util.format_value(0) , "0")
self.assertEqual(util.format_value(1) , "1")
self.assertEqual(util.format_value(12) , "12")
self.assertEqual(util.format_value(123) , "123")
self.assertEqual(util.format_value(1234) , "1.23k")
self.assertEqual(util.format_value(12345) , "12.34k")
self.assertEqual(util.format_value(123456) , "123.45k")
self.assertEqual(util.format_value(1234567) , "1.23M")
self.assertEqual(util.format_value(12345678) , "12.34M")
self.assertEqual(util.format_value(123456789) , "123.45M")
self.assertEqual(util.format_value(1234567890), "1.23G")
def test_combine_dict(self):
self.assertEqual(
util.combine_dict({}, {}),
{})
self.assertEqual(
util.combine_dict({1: 1, 2: 2}, {2: 4, 4: 8}),
{1: 1, 2: 4, 4: 8})
self.assertEqual(
util.combine_dict(
{1: {11: 22, 12: 24}, 2: {13: 26, 14: 28}},
{1: {11: 33, 13: 39}, 2: "str"}),
{1: {11: 33, 12: 24, 13: 39}, 2: "str"})
self.assertEqual(
util.combine_dict(
{1: {2: {3: {4: {"1": "a", "2": "b"}}}}},
{1: {2: {3: {4: {"1": "A", "3": "C"}}}}}),
{1: {2: {3: {4: {"1": "A", "2": "b", "3": "C"}}}}})
def test_transform_dict(self):
d = {}
util.transform_dict(d, str)
self.assertEqual(d, {})
d = {1: 123, 2: "123", 3: True, 4: None}
util.transform_dict(d, str)
self.assertEqual(
d, {1: "123", 2: "123", 3: "True", 4: "None"})
d = {1: 123, 2: "123", 3: "foo", 4: {11: 321, 12: "321", 13: "bar"}}
util.transform_dict(d, text.parse_int)
self.assertEqual(
d, {1: 123, 2: 123, 3: 0, 4: {11: 321, 12: 321, 13: 0}})
def test_filter_dict(self):
d = {}
r = util.filter_dict(d)
self.assertEqual(r, d)
self.assertIsNot(r, d)
d = {"foo": 123, "bar": [], "baz": None}
r = util.filter_dict(d)
self.assertEqual(r, d)
self.assertIsNot(r, d)
d = {"foo": 123, "_bar": [], "__baz__": None}
r = util.filter_dict(d)
self.assertEqual(r, {"foo": 123})
def test_enumerate_reversed(self):
seq = [11, 22, 33]
result = [(3, 33), (2, 22), (1, 11)]
def gen():
for i in seq:
yield i
def gen_2():
yield from seq
def assertEqual(it1, it2):
ae = self.assertEqual
for i1, i2 in itertools.zip_longest(it1, it2):
ae(i1, i2)
assertEqual(
util.enumerate_reversed(seq), [(2, 33), (1, 22), (0, 11)])
assertEqual(
util.enumerate_reversed(seq, 1), result)
assertEqual(
util.enumerate_reversed(seq, 2), [(4, 33), (3, 22), (2, 11)])
assertEqual(
util.enumerate_reversed(gen(), 0, len(seq)),
[(2, 33), (1, 22), (0, 11)])
assertEqual(
util.enumerate_reversed(gen(), 1, len(seq)), result)
assertEqual(
util.enumerate_reversed(gen_2(), 1, len(seq)), result)
assertEqual(
util.enumerate_reversed(gen_2(), 2, len(seq)),
[(4, 33), (3, 22), (2, 11)])
def test_number_to_string(self, f=util.number_to_string):
self.assertEqual(f(1) , "1")
self.assertEqual(f(1.0) , "1.0")
self.assertEqual(f("1.0") , "1.0")
self.assertEqual(f([1]) , [1])
self.assertEqual(f({1: 2}), {1: 2})
self.assertEqual(f(True) , True)
self.assertEqual(f(None) , None)
def test_to_string(self, f=util.to_string):
self.assertEqual(f(1) , "1")
self.assertEqual(f(1.0) , "1.0")
self.assertEqual(f("1.0"), "1.0")
self.assertEqual(f("") , "")
self.assertEqual(f(None) , "")
self.assertEqual(f(0) , "")
self.assertEqual(f(["a"]), "a")
self.assertEqual(f([1]) , "1")
self.assertEqual(f(["a", "b", "c"]), "a, b, c")
self.assertEqual(f([1, 2, 3]), "1, 2, 3")
def test_datetime_to_timestamp(self, f=util.datetime_to_timestamp):
self.assertEqual(f(util.EPOCH), 0.0)
self.assertEqual(f(datetime.datetime(2010, 1, 1)), 1262304000.0)
self.assertEqual(f(datetime.datetime(2010, 1, 1, 0, 0, 0, 128000)),
1262304000.128000)
with self.assertRaises(TypeError):
f(None)
def test_datetime_to_timestamp_string(
self, f=util.datetime_to_timestamp_string):
self.assertEqual(f(util.EPOCH), "0")
self.assertEqual(f(datetime.datetime(2010, 1, 1)), "1262304000")
self.assertEqual(f(None), "")
def test_universal_none(self):
obj = util.NONE
self.assertFalse(obj)
self.assertEqual(len(obj), 0)
self.assertEqual(int(obj), 0)
self.assertEqual(hash(obj), 0)
self.assertEqual(str(obj), str(None))
self.assertEqual(repr(obj), repr(None))
self.assertEqual(format(obj), str(None))
self.assertEqual(format(obj, "%F"), str(None))
self.assertIs(obj.attr, obj)
self.assertIs(obj["key"], obj)
self.assertIs(obj(), obj)
self.assertIs(obj(1, "a"), obj)
self.assertIs(obj(foo="bar"), obj)
self.assertIs(iter(obj), obj)
self.assertEqual(util.json_dumps(obj), "null")
self.assertLess(obj, "foo")
self.assertLessEqual(obj, None)
self.assertTrue(obj == obj)
self.assertFalse(obj == 0)
self.assertFalse(obj != obj)
self.assertGreater(123, obj)
self.assertGreaterEqual(1.23, obj)
self.assertEqual(obj + 123, obj)
self.assertEqual(obj - 123, obj)
self.assertEqual(obj * 123, obj)
# self.assertEqual(obj @ 123, obj)
self.assertEqual(obj / 123, obj)
self.assertEqual(obj // 123, obj)
self.assertEqual(obj % 123, obj)
self.assertEqual(123 + obj, obj)
self.assertEqual(123 - obj, obj)
self.assertEqual(123 * obj, obj)
# self.assertEqual(123 @ obj, obj)
self.assertEqual(123 / obj, obj)
self.assertEqual(123 // obj, obj)
self.assertEqual(123 % obj, obj)
self.assertEqual(obj << 123, obj)
self.assertEqual(obj >> 123, obj)
self.assertEqual(obj & 123, obj)
self.assertEqual(obj ^ 123, obj)
self.assertEqual(obj | 123, obj)
self.assertEqual(123 << obj, obj)
self.assertEqual(123 >> obj, obj)
self.assertEqual(123 & obj, obj)
self.assertEqual(123 ^ obj, obj)
self.assertEqual(123 | obj, obj)
self.assertEqual(-obj, obj)
self.assertEqual(+obj, obj)
self.assertEqual(~obj, obj)
self.assertEqual(abs(obj), obj)
mapping = {}
mapping[obj] = 123
self.assertIn(obj, mapping)
self.assertEqual(mapping[obj], 123)
array = [1, 2, 3]
self.assertEqual(array[obj], 1)
if platform.python_implementation().lower() == "cpython":
self.assertTrue(time.localtime(obj))
i = 0
for _ in obj:
i += 1
self.assertEqual(i, 0)
class TestExtractor():
category = "test_category"
subcategory = "test_subcategory"
basecategory = "test_basecategory"
class TestExtractorParent(TestExtractor):
category = "test_category"
subcategory = "test_subcategory_parent"
class TestExtractorAlt(TestExtractor):
category = "test_category_alt"
subcategory = "test_subcategory"
if __name__ == "__main__":
unittest.main()