diff --git a/base_test_case.py b/base_test_case.py new file mode 100644 index 0000000..dd3fe5e --- /dev/null +++ b/base_test_case.py @@ -0,0 +1,118 @@ +# Python standard library imports: +import unittest + +# Our imports: +from .string_utils import snake_to_mixed + + +class BaseTestCase(unittest.TestCase): + """ + + Extend this with your test cases to get some sweet shit! + + - Notes: + - Never override the mixed case setup/teardown methods! Those are how + + + - Provides: + + - Instance methods: + + - `self.set_up()`: subclasses should use this for their + test-by-test set up + + - `self.tear_down()`: subclasses should use this for their + test-by-test tear down + + - Classmethods: + + - `cls.set_up_class():`: subclasses should use this for their + class-level set up + + - `cls.tear_down_class()`: subclasses should use this for their + class-level tear down + + - Method aliases: + + - If you call any snake_case method call (instance method or + classmethod) and that method does not exist, BaseTestCase will + attempt to call the mixedCase version, e.g.: + - `self.assert_equal()`: aliases self.assertEqual + - `self.assert_true()`: aliases self.assertTrue + """ + + # -------------------- + # Magic for snake_case + # -------------------- + class __metaclass__(type): + def __getattr__(cls, name): + """ + + This provides snake_case aliases for mixedCase classmethods. + + For instance, if you were to ask for `cls.tear_down_class`, and it + didn't exist, you would transparently get a reference to + `cls.tearDownClass` instead. + + """ + + name = snake_to_mixed(name) + return type.__getattribute__(cls, name) + + def __getattr__(self, name): + """ + + This provides snake_case aliases for mixedCase instance methods. + + For instance, if you were to ask for `self.assert_equal`, and it + didn't exist, you would transparently get a reference to + `self.assertEqual` instead. + + """ + + mixed_name = snake_to_mixed(name) + mixed_attr = None + + try: + mixed_attr = object.__getattribute__(self, mixed_name) + except: + pass + + if mixed_attr: + return mixed_attr + + return self.__getattribute__(name) + + + # --------------------------- + # Set Up and Tear Down stuff + # --------------------------- + + @classmethod + def setUpClass(cls): + cls.set_up_class() + + @classmethod + def tearDownClass(cls): + cls.tear_down_class() + + def setUp(self): + self.set_up() + + def tearDown(self): + self.tear_down() + + @classmethod + def set_up_class(cls): + pass + + @classmethod + def tear_down_class(cls): + pass + + + def set_up(self): + pass + + def tear_down(self): + pass diff --git a/hashing.py b/hashing.py new file mode 100644 index 0000000..c3ea5d5 --- /dev/null +++ b/hashing.py @@ -0,0 +1,12 @@ +import md5 +import base64 +import zlib + +def to_md5(hashable): + # create a hashed key + m = md5.new() + m.update(hashable) + return m.hexdigest() + +def to_compressed(string): + return base64.b64encode(zlib.compress(string)) diff --git a/random_utils.py b/random_utils.py new file mode 100644 index 0000000..423322a --- /dev/null +++ b/random_utils.py @@ -0,0 +1,21 @@ +import random + +def do_weighted_draw(weights): + total = 0; + current_total = 0; + bucket = 0; + + for weight in weights: + total += weight + + rand = random.random() * total + + for weight in weights: + current_total += weight + + if rand > current_total: + bucket += 1 + else: + break + + return bucket