From d8a7a96685568be715af551218b85d1b0c21c05e Mon Sep 17 00:00:00 2001 From: Anthony Blackshaw Date: Tue, 16 Aug 2016 10:26:02 +0100 Subject: [PATCH] - Removed presets from factory (with the benefit of hindsight presets created more problems than they solved). - Added a `document` property to makers which is set to the target document when assemble or finish is called using the `target` context method (blueprints now use this). --- mongoframes/factory/__init__.py | 24 +++--- mongoframes/factory/blueprints.py | 94 ++++++------------------ mongoframes/factory/makers/__init__.py | 49 +++++++++--- mongoframes/factory/makers/dates.py | 2 + mongoframes/factory/makers/images.py | 1 + mongoframes/factory/makers/numbers.py | 4 + mongoframes/factory/makers/selections.py | 4 + mongoframes/factory/makers/text.py | 8 ++ mongoframes/factory/presets.py | 55 -------------- setup.py | 4 +- tests/factory/makers/test_makers.py | 26 +++++-- tests/factory/test_blueprints.py | 48 +++++------- tests/factory/test_factory.py | 41 ++++------- tests/factory/test_presets.py | 55 -------------- 14 files changed, 141 insertions(+), 274 deletions(-) delete mode 100644 mongoframes/factory/presets.py delete mode 100644 tests/factory/test_presets.py diff --git a/mongoframes/factory/__init__.py b/mongoframes/factory/__init__.py index 94b8b9b..26cdfd8 100644 --- a/mongoframes/factory/__init__.py +++ b/mongoframes/factory/__init__.py @@ -33,16 +33,6 @@ class Factory: `Frame` classes to modify the insert behaviour for factories. """ - def __init__(self, presets=None): - # A list of presets for the factory - self._presets = presets or [] - - # Read-only properties - - @property - def presets(self): - return self._presets - # Public methods def assemble(self, blueprint, quota): @@ -54,7 +44,7 @@ def assemble(self, blueprint, quota): # Assemble the documents documents = [] for i in range(0, int(quota)): - documents.append(blueprint.assemble(self.presets)) + documents.append(blueprint.assemble()) return documents @@ -67,7 +57,7 @@ def finish(self, blueprint, documents): # Finish the documents finished = [] for document in documents: - finished.append(blueprint.finish(document, self.presets)) + finished.append(blueprint.finish(document)) return finished @@ -80,10 +70,14 @@ def populate(self, blueprint, documents): # Convert the documents to frame instances frames = [] for document in documents: - [frame_document, meta_document] = document + # Separate out any meta fields + meta_document = {} + for field_name in blueprint._meta_fields: + meta_document[field_name] = document[field_name] + document.pop(field_name) # Initialize the frame - frame = blueprint.get_frame_cls()(frame_document) + frame = blueprint.get_frame_cls()(document) # Apply any meta fields for key, value in meta_document.items(): @@ -113,4 +107,4 @@ def reassemble(self, blueprint, fields, documents): # Reassemble the documents for document in documents: - blueprint.reassemble(fields, document, self.presets) \ No newline at end of file + blueprint.reassemble(fields, document) \ No newline at end of file diff --git a/mongoframes/factory/blueprints.py b/mongoframes/factory/blueprints.py index 3507d16..b5e57ed 100644 --- a/mongoframes/factory/blueprints.py +++ b/mongoframes/factory/blueprints.py @@ -1,6 +1,6 @@ from blinker import signal +from collections import OrderedDict -from mongoframes.factory.presets import Preset from mongoframes.factory.makers import Maker __all__ = ['Blueprint'] @@ -19,6 +19,10 @@ def __new__(meta, name, bases, dct): # field the instruction refers to and the value is a `Maker` type for # generating a value for that field. dct['_instructions'] = dct.get('_instructions') or {} + + # Ensure the instructions are an ordered dictionary + dct['_instructions'] = OrderedDict(dct['_instructions']) + for k, v in dct.items(): if isinstance(v, Maker): dct['_instructions'][k] = v @@ -68,107 +72,51 @@ def get_meta_fields(cls): # Factory methods @classmethod - def assemble(cls, presets=None): - """Assemble a single document using the blueprint and presets""" - presets = presets or [] - + def assemble(cls): + """Assemble a single document using the blueprint""" document = {} - - fields = cls._frame_cls.get_fields() | cls._meta_fields - - for field_name in fields: - - # Use a dedicated instruction if we have one - if field_name in cls._instructions: - maker = cls._instructions[field_name] - if maker: - document[field_name] = maker() - continue - - # Check for a preset - preset = Preset.find(presets, field_name) - if preset: - document[field_name] = preset.maker() - continue - + for field_name, maker in cls._instructions.items(): + with maker.target(document): + document[field_name] = maker() return document @classmethod - def finish(cls, document, presets=None): + def finish(cls, document): """ Take a pre-assembled document and convert all dynamic values to static values. """ - presets = presets or [] - document_copy = {} - meta_document = {} for field_name, value in document.items(): - - # Use a dedicated instruction if we have one - if field_name in cls._instructions: - maker = cls._instructions[field_name] - if field_name in cls._meta_fields: - meta_document[field_name] = maker(value) - else: - document_copy[field_name] = maker(value) - continue - - # Check for a preset - preset = Preset.find(presets, field_name) - if preset: - if field_name in cls._meta_fields: - meta_document[field_name] = preset.maker(value) - else: - document_copy[field_name] = preset.maker(value) - continue - - return (document_copy, meta_document) + maker = cls._instructions[field_name] + with maker.target(document): + document_copy[field_name] = maker(value) + return document_copy @classmethod - def reassemble(cls, fields, document, presets=None): + def reassemble(cls, fields, document): """ Take a pre-assembled document and reassemble the given set of fields - for it. + for it in place. """ - - # Filter the field list to just those we can set against the frame - fields = [f for f in fields \ - if f in cls._frame_cls.get_fields() | cls._meta_fields] - - for field_name in fields: - - # Use a dedicated instruction if we have one - if field_name in cls._instructions: + for field_name in cls._instructions: + if field_name in fields: maker = cls._instructions[field_name] - if maker: + with maker.target(document): document[field_name] = maker() - continue - - # Check for a preset - preset = Preset.find(presets, field_name) - if preset: - document[field_name] = preset.maker() - continue @classmethod - def reset(cls, presets=None): + def reset(cls): """ Reset the blueprint. Blueprints are typically reset before being used to assemble a quota of documents. Resetting a blueprint will in turn reset all the makers for the blueprint allowing internal counters and a like to be reset. """ - presets = presets or [] - # Reset instructions for maker in cls._instructions.values(): maker.reset() - # Check for a preset - for preset in presets: - preset.maker.reset() - # Events @classmethod diff --git a/mongoframes/factory/makers/__init__.py b/mongoframes/factory/makers/__init__.py index eca7cc8..214a477 100644 --- a/mongoframes/factory/makers/__init__.py +++ b/mongoframes/factory/makers/__init__.py @@ -1,3 +1,4 @@ +import contextlib import random import faker @@ -21,11 +22,21 @@ class Maker: A base class for all Maker classes. """ + def __init__(self): + + # The document the maker is assembling/finishing data for + self._document = None + def __call__(self, *args): if args: return self._finish(*args) return self._assemble() + @property + def document(self): + # Return the target document + return self._document + def reset(self): """Reset the maker instance""" pass @@ -36,6 +47,12 @@ def _assemble(self): def _finish(self, value): return value + @contextlib.contextmanager + def target(self, document): + self._document = document + yield + self._document = None + class DictOf(Maker): """ @@ -44,6 +61,7 @@ class DictOf(Maker): """ def __init__(self, table): + super().__init__() # The table of keyword arguments that will be used to generate the # dictionary. @@ -78,6 +96,7 @@ class Faker(Maker): default_locale = 'en_US' def __init__(self, provider, assembler=True, locale=None, **kwargs): + super().__init__() # The provider that will be used to generate the value self._provider = provider @@ -121,6 +140,7 @@ class Lambda(Maker): """ def __init__(self, func, assembler=True, finisher=False): + super().__init__() assert assembler or finisher, \ 'Either `assembler` or `finisher` must be true for lambda' @@ -151,6 +171,7 @@ class ListOf(Maker): """ def __init__(self, maker, quantity, reset_maker=False): + super().__init__() # The maker used to generate each value in the list self._maker = maker @@ -184,6 +205,7 @@ class Reference(Maker): """ def __init__(self, frame_cls, field_name, value): + super().__init__() # The `Frame` class that will be used to obtain the referenced document self._frame_cls = frame_cls @@ -224,6 +246,7 @@ class Static(Maker): """ def __init__(self, value, assembler=True): + super().__init__() # The value to return self._value = value @@ -248,29 +271,30 @@ class SubFactory(Maker): A maker that makes sub-documents. """ - def __init__(self, blueprint, presets=None): + def __init__(self, blueprint): + super().__init__() # The blueprint to produce self._blueprint = blueprint - # A list of presets to apply with the blueprint - self._presets = presets or [] - def reset(self): - """Reset the associated blueprint and presets""" - self._blueprint.reset(self._presets) + """Reset the blueprint for the sub-factory""" + self._blueprint.reset() def _assemble(self): - return self._blueprint.assemble(self._presets) + return self._blueprint.assemble() def _finish(self, value): - [frame_document, meta_document] = self._blueprint.finish( - value, - self._presets - ) + document = self._blueprint.finish(value) + + # Separate out any meta fields + meta_document = {} + for field_name in self._blueprint._meta_fields: + meta_document[field_name] = document[field_name] + document.pop(field_name) # Initialize the sub-frame - sub_frame = self._blueprint.get_frame_cls()(frame_document) + sub_frame = self._blueprint.get_frame_cls()(document) # Apply any meta fields for key, value in meta_document.items(): @@ -290,6 +314,7 @@ def __init__(self, assembler=True, max_attempts=1000 ): + super().__init__() # The maker that will generate values self._maker = maker diff --git a/mongoframes/factory/makers/dates.py b/mongoframes/factory/makers/dates.py index 39fadc2..25bda0f 100644 --- a/mongoframes/factory/makers/dates.py +++ b/mongoframes/factory/makers/dates.py @@ -19,6 +19,8 @@ class DateBetween(Maker): """ def __init__(self, min_date, max_date): + super().__init__() + # The date range between which a date will be selected self._min_date = min_date self._max_date = max_date diff --git a/mongoframes/factory/makers/images.py b/mongoframes/factory/makers/images.py index 6d806cf..2bafc79 100644 --- a/mongoframes/factory/makers/images.py +++ b/mongoframes/factory/makers/images.py @@ -21,6 +21,7 @@ def __init__(self, service_url='//fakeimg.pl', service_formatter=None ): + super().__init__() # The size of the image to generate self._width = width diff --git a/mongoframes/factory/makers/numbers.py b/mongoframes/factory/makers/numbers.py index ca7ecc5..6798781 100644 --- a/mongoframes/factory/makers/numbers.py +++ b/mongoframes/factory/makers/numbers.py @@ -13,6 +13,8 @@ class Counter(Maker): """ def __init__(self, start_from=1, step=1): + super().__init__() + self._start_from = int(start_from) self._step = step self._counter = self._start_from @@ -32,6 +34,8 @@ class Float(Maker): """ def __init__(self, min_value, max_value): + super().__init__() + self._min_value = min_value self._max_value = max_value diff --git a/mongoframes/factory/makers/selections.py b/mongoframes/factory/makers/selections.py index 7f0c9b0..c38ef57 100644 --- a/mongoframes/factory/makers/selections.py +++ b/mongoframes/factory/makers/selections.py @@ -21,6 +21,7 @@ class Cycle(Maker): """ def __init__(self, items): + super().__init__() # The list of makers/values to select from self._items = items @@ -60,6 +61,7 @@ class OneOf(Maker): """ def __init__(self, items, weights=None): + super().__init__() # The list of makers/values to select from self._items = items @@ -119,6 +121,7 @@ class RandomReference(Maker): """ def __init__(self, frame_cls, constraint=None): + super().__init__() # The frame class that will be used to select a reference with self._frame_cls = frame_cls @@ -166,6 +169,7 @@ def __init__( weights=None, with_replacement=False ): + super().__init__() # The list of makers/values to select from self._items = items diff --git a/mongoframes/factory/makers/text.py b/mongoframes/factory/makers/text.py index 2c63c96..b19faf3 100644 --- a/mongoframes/factory/makers/text.py +++ b/mongoframes/factory/makers/text.py @@ -22,6 +22,7 @@ class Code(Maker): default_charset = string.ascii_uppercase + string.digits def __init__(self, length, charset=None): + super().__init__() # If no charset is provided use the default if not charset: @@ -45,6 +46,7 @@ class Join(Maker): """ def __init__(self, items, sep=' '): + super().__init__() # The list of makers/values that will be joined self._items = items @@ -90,6 +92,8 @@ class Lorem(Maker): """ def __init__(self, text_type, quantity): + super().__init__() + # The type of text structure to generate self._text_type = text_type @@ -147,6 +151,8 @@ class Markov(Maker): _dbs = {} def __init__(self, db, text_type, quantity): + super().__init__() + # The database to generate the text from self._db = db @@ -288,6 +294,8 @@ class Sequence(Maker): """ def __init__(self, template, start_from=1): + super().__init__() + self._template = template self._start_from = start_from self._index = start_from diff --git a/mongoframes/factory/presets.py b/mongoframes/factory/presets.py deleted file mode 100644 index cb63d5b..0000000 --- a/mongoframes/factory/presets.py +++ /dev/null @@ -1,55 +0,0 @@ -__all__ = ['Preset'] - - -class Preset: - """ - Presets match field names to makers (any function that can produce a value - for a field). They provide default makers for fields that are not directly - defined in a `Blueprints` instructions. - - The pattern used to match a preset with a maker should be a compiled regular - expression or a string. If a string is provided then the match must match - exactly. - """ - - def __init__(self, pattern, maker): - - # The pattern used to associate a field name with a maker - self._pattern = pattern - - # The maker that will be used to produce values for this field - self._maker = maker - - # Read-only properties - - @property - def maker(self): - return self._maker - - @property - def pattern(self): - return self._pattern - - # Public methods - - def match(self, field_name): - """ - Return True if the given field name matches the preset's pattern. - """ - - if hasattr(self._pattern, 'match'): - return self._pattern.match(field_name) is not None - - return self._pattern == field_name - - # Class methods - - @classmethod - def find(cls, presets, field_name): - """ - Search a list of presets and return the first to match the specified - field name or None if there are not matches. - """ - for preset in presets: - if preset.match(field_name): - return preset \ No newline at end of file diff --git a/setup.py b/setup.py index 705fb75..8155d1e 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html - version='1.2.3', + version='1.2.4', description='A fast unobtrusive MongoDB ODM for Python', long_description=long_description, @@ -46,7 +46,7 @@ # 3 - Alpha # 4 - Beta # 5 - Production/Stable - 'Development Status :: 3 - Alpha', + 'Development Status :: 4 - Beta', # Indicate who your project is intended for 'Intended Audience :: Developers', diff --git a/tests/factory/makers/test_makers.py b/tests/factory/makers/test_makers.py index f1eda3f..7586dce 100644 --- a/tests/factory/makers/test_makers.py +++ b/tests/factory/makers/test_makers.py @@ -2,7 +2,6 @@ from mongoframes.factory import blueprints from mongoframes.factory import makers -from mongoframes.factory import presets from mongoframes.factory import quotas from mongoframes.factory.makers import selections as selection_makers from mongoframes.factory.makers import text as text_makers @@ -10,6 +9,22 @@ from tests.fixtures import * +def test_maker(): + """ + The base maker class should provide context for the current target document. + """ + + document = {'foo': 'bar'} + maker = makers.Maker() + + # Check the target for the maker is correctly set using the `target` context + # method. + with maker.target(document): + assert maker.document == document + + # Once the maker falls out of context check the document has been unset + assert maker.document == None + def test_dict_of(): """ `DictOf` makers should return a dictionary where each key's value is either @@ -211,8 +226,7 @@ def test_static(): def test_sub_factory(mocker): """ - `SubFactory` makers should return a sub-frame/document using a blueprint and - optionally a list of presets. + `SubFactory` makers should return a sub-frame/document using a blueprint. """ # Define a blueprint @@ -220,13 +234,11 @@ class InventoryBlueprint(blueprints.Blueprint): _frame_cls = Inventory + gold = makers.Static(10) skulls = makers.Static(100) - # Define a preset - preset = presets.Preset('gold', makers.Static(10)) - # Configure the maker - maker = makers.SubFactory(InventoryBlueprint, [preset]) + maker = makers.SubFactory(InventoryBlueprint) # Check the assembled result assembled = maker._assemble() diff --git a/tests/factory/test_blueprints.py b/tests/factory/test_blueprints.py index 1dffe3c..8662ab6 100644 --- a/tests/factory/test_blueprints.py +++ b/tests/factory/test_blueprints.py @@ -2,7 +2,6 @@ from mongoframes.factory import blueprints from mongoframes.factory import makers -from mongoframes.factory import presets from tests.fixtures import * @@ -33,13 +32,11 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') - # Build a list if presets - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - # Check the assembled output of the blueprint is as expected - assembled = DragonBlueprint.assemble(my_presets) + assembled = DragonBlueprint.assemble() assert assembled == { 'breed': 'Fire-drake', @@ -60,19 +57,17 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') - # Build a list if presets - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - # Check the finished output of the blueprint is as expected - finished, meta_finished = DragonBlueprint.finish( - DragonBlueprint.assemble(my_presets), - my_presets - ) + finished = DragonBlueprint.finish(DragonBlueprint.assemble()) - assert finished == {'breed': 'Fire-drake', 'name': 'Burt'} - assert meta_finished == {'dummy_prop': 'foo'} + assert finished == { + 'breed': 'Fire-drake', + 'dummy_prop': 'foo', + 'name': 'Burt' + } def test_blueprint_reassemble(): """ @@ -87,27 +82,24 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') - # Build a list if presets - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - # Check the assembled output of the blueprint is as expected - assembled = DragonBlueprint.assemble(my_presets) + assembled = DragonBlueprint.assemble() - # Re-configure the blueprint and presets + # Re-configure the blueprint class DragonBlueprint(blueprints.Blueprint): _frame_cls = Dragon _meta_fields = {'dummy_prop'} name = makers.Static('Fred') + breed = makers.Static('Cold-drake') dummy_prop = makers.Static('bar') - my_presets = [presets.Preset('breed', makers.Static('Cold-drake'))] - # Check the reassembled output for the blueprint is as expected - DragonBlueprint.reassemble({'breed', 'name'}, assembled, my_presets) + DragonBlueprint.reassemble({'breed', 'name'}, assembled) assert assembled == { 'breed': 'Cold-drake', @@ -118,7 +110,7 @@ class DragonBlueprint(blueprints.Blueprint): def test_blueprint_reset(mocker): """ The `Blueprint.reset` method should call the reset of all makers in the - blueprints instructions and any in the given list of presets. + blueprints instructions. """ # Configure the blueprint @@ -128,20 +120,18 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') - # Build a list if presets - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - # Spy on the maker reset methods - mocker.spy(my_presets[0].maker, 'reset') mocker.spy(DragonBlueprint._instructions['name'], 'reset') + mocker.spy(DragonBlueprint._instructions['breed'], 'reset') mocker.spy(DragonBlueprint._instructions['dummy_prop'], 'reset') # Reset the blueprint - DragonBlueprint.reset(my_presets) + DragonBlueprint.reset() # Check each maker reset method was called - assert my_presets[0].maker.reset.call_count == 1 assert DragonBlueprint._instructions['name'].reset.call_count == 1 + assert DragonBlueprint._instructions['breed'].reset.call_count == 1 assert DragonBlueprint._instructions['dummy_prop'].reset.call_count == 1 \ No newline at end of file diff --git a/tests/factory/test_factory.py b/tests/factory/test_factory.py index a5c0ae9..225509e 100644 --- a/tests/factory/test_factory.py +++ b/tests/factory/test_factory.py @@ -1,23 +1,11 @@ from mongoframes.factory import Factory from mongoframes.factory import blueprints from mongoframes.factory import makers -from mongoframes.factory import presets from mongoframes.factory import quotas from tests.fixtures import * -def test_factory_read_only_props(): - """ - The `Factory` class read-only properties should return the correct values. - """ - - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - factory = Factory(my_presets) - - # Check the read-only properties of the preset return the correct values - assert factory.presets == my_presets - def test_factory_assemble(): """ The `Factory.assemble` method should return a quota of assembled @@ -31,11 +19,11 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') # Configure the factory - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - factory = Factory(my_presets) + factory = Factory() # Assemble a list of documents using the factory documents = factory.assemble(DragonBlueprint, quotas.Quota(10)) @@ -63,11 +51,11 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') # Configure the factory - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - factory = Factory(my_presets) + factory = Factory() # Assemble a list of documents using the factory documents = factory.assemble(DragonBlueprint, quotas.Quota(10)) @@ -77,10 +65,11 @@ class DragonBlueprint(blueprints.Blueprint): # Check the assembled output of the factory is as expected for document in documents: - assert document == ( - {'breed': 'Fire-drake', 'name': 'Burt'}, - {'dummy_prop': 'foo'} - ) + assert document == { + 'breed': 'Fire-drake', + 'name': 'Burt', + 'dummy_prop': 'foo' + } def test_factory_populate(mongo_client, mocker): """ @@ -95,11 +84,11 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') # Configure the factory - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - factory = Factory(my_presets) + factory = Factory() # Assemble a list of documents using the factory documents = factory.assemble(DragonBlueprint, quotas.Quota(10)) @@ -142,11 +131,11 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Burt') + breed = makers.Static('Fire-drake') dummy_prop = makers.Static('foo') # Configure the factory - my_presets = [presets.Preset('breed', makers.Static('Fire-drake'))] - factory = Factory(my_presets) + factory = Factory() # Assemble a list of documents using the factory documents = factory.assemble(DragonBlueprint, quotas.Quota(10)) @@ -158,10 +147,10 @@ class DragonBlueprint(blueprints.Blueprint): _meta_fields = {'dummy_prop'} name = makers.Static('Fred') + breed = makers.Static('Cold-drake') dummy_prop = makers.Static('bar') - my_presets = [presets.Preset('breed', makers.Static('Cold-drake'))] - factory = Factory(my_presets) + factory = Factory() # Reassemble the documents factory.reassemble(DragonBlueprint, {'breed', 'name'}, documents) diff --git a/tests/factory/test_presets.py b/tests/factory/test_presets.py deleted file mode 100644 index 2c7cd71..0000000 --- a/tests/factory/test_presets.py +++ /dev/null @@ -1,55 +0,0 @@ -import re - -from mongoframes.factory import makers -from mongoframes.factory import presets - - -def test_preset_read_only_props(): - """ - The `Preset` class read-only properties should return the correct values. - """ - - maker = makers.Static('bar') - preset = presets.Preset('foo', maker) - - # Check the read-only properties of the preset return the correct values - assert preset.pattern == 'foo' - assert preset.maker == maker - -def test_preset_match(): - """ - The `Preset.match` method should return true if a field name matches a - pattern. - """ - - # Configure the preset with a simple string match - preset = presets.Preset('foo', makers.Static('bar')) - assert preset.match('foo') == True - assert preset.match('bar') == False - - # Configure the preset with a regular expression match - preset = presets.Preset(re.compile('foo.*'), makers.Static('bar')) - assert preset.match('foobar') == True - assert preset.match('barfoo') == False - -def test_preset_find(): - """ - The `Preset.find` class method should return the first preset that matches - the given field name. - """ - my_presets = [ - presets.Preset('foo', makers.Static('foo')), - presets.Preset('bar', makers.Static('bar')), - presets.Preset('zee', makers.Static('zee')), - presets.Preset(re.compile('foo.*'), makers.Static('foo*')), - presets.Preset(re.compile('bar.*'), makers.Static('bar*')), - presets.Preset(re.compile('zee.*'), makers.Static('zee*')) - ] - - # Check that `Preset.find` returns the expected presets - assert presets.Preset.find(my_presets, 'foo') == my_presets[0] - assert presets.Preset.find(my_presets, 'bar') == my_presets[1] - assert presets.Preset.find(my_presets, 'zee') == my_presets[2] - assert presets.Preset.find(my_presets, 'foo1') == my_presets[3] - assert presets.Preset.find(my_presets, 'bar2') == my_presets[4] - assert presets.Preset.find(my_presets, 'zee3') == my_presets[5] \ No newline at end of file