def bound_data(self, data, initial): if self.disabled: return initial try: return json_decode(data) except ValueError: return JsonField.InvalidInput(data)
def create_auto_test_class(fixture, callback): """ Crée un test automatisé à partir d'une fixture complète :param fixture: Chemin vers la fixture :param callback: Fonction retournant les résultats à vérifier :return: Classe de test """ import os import tempfile import decimal # Classe de test transactionnelle supprimant la fixture à la fin class AutoTest(Test): @classmethod def tearDownClass(cls): for fixture in cls.fixtures: os.remove(fixture) super().tearDownClass() # Récupération du nom depuis le fichier name, ext = os.path.splitext(os.path.basename(fixture)) name = ''.join(x.capitalize() or '_' for x in name.split('_')) + 'TestCase' # Lecture des données with open(fixture, 'r') as file: data = json_decode(file.read()) # Création d'une fixture temporaire à partir des modèles models = data.pop('models', {}) with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False, suffix='.json') as temp_file: temp_file.write(json_encode(models)) temp_file.flush() # Création de la classe de test test_class = type(name, (AutoTest, ), dict(data=data, fixtures=[temp_file.name])) # Création des méthodes de test tests = data.pop('tests') for index, test in enumerate(tests, start=1): def test_method(self, test=test): data = callback(test) with self.subTest(): for result in test.get('results', []): fields = result.get('fields', []) value = result.get('value', None) current = data for field in fields: current = current[field] # Conversion explicite en décimal if isinstance(current, decimal.Decimal): value = decimal.Decimal(str(value)) operator = OPERATORS.get(result.get('operator', '==')) operator(self, current, value) test_name = 'test_{}'.format( slugify(test.get('name', index)).replace('-', '_')) setattr(test_class, test_name, test_method) return test_class
def create_auto_test_class(fixture, callback): """ Creates an automated test from a complete fixture :param fixture: Path to the fixture :param callback: Function returning results to be verified :return: Test class """ import os import tempfile import decimal # Transactional test class removing fixture at end class AutoTest(Test): @classmethod def tearDownClass(cls): for fixture in cls.fixtures: os.remove(fixture) super().tearDownClass() # Recover name from file name, ext = os.path.splitext(os.path.basename(fixture)) name = ''.join(x.capitalize() or '_' for x in name.split('_')) + 'TestCase' # Read the data with open(fixture, 'r') as file: data = json_decode(file.read()) # Creating a temporary fixture from templates models = data.pop('models', {}) with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False, suffix='.json') as temp_file: temp_file.write(json_encode(models)) temp_file.flush() # Created test class test_class = type(name, (AutoTest, ), dict(data=data, fixtures=[temp_file.name])) # Created test method tests = data.pop('tests') for index, test in enumerate(tests, start=1): def test_method(self, test=test): data = callback(test) with self.subTest(): for result in test.get('results', []): fields = result.get('fields', []) value = result.get('value', None) current = data for field in fields: current = current[field] # Explicit conversion to decimal if isinstance(current, decimal.Decimal): value = decimal.Decimal(str(value)) operator = OPERATORS.get(result.get('operator', '==')) operator(self, current, value) test_name = 'test_{}'.format( slugify(test.get('name', index)).replace('-', '_')) setattr(test_class, test_name, test_method) return test_class
def to_python(self, value): if value is None or value == '': return {} if not self.null else None try: while isinstance(value, str): value = json_decode(value) except ValueError: pass if isinstance(value, dict): return JsonDict(**value) elif isinstance(value, str): return JsonString(value) elif isinstance(value, list): return JsonList(value) return value
def to_python(self, value): if self.disabled: return value from common.fields import JsonString if value in self.empty_values: return None elif isinstance(value, (list, dict, int, float, JsonString)): return value try: converted = json_decode(value) except ValueError: raise forms.ValidationError( self.error_messages['invalid'], code='invalid', params={'value': value}, ) if isinstance(converted, str): return JsonString(converted) else: return converted
def url_value(filter, value): """ Transforme la valeur dans l'URL à partir du filtre :param filter: Filtre :param value: Valeur :return: Valeur """ if not isinstance(value, str): return value if filter: if any(filter.endswith(lookup) for lookup in ('__in', '__range', '__any', '__all')): return value.split(',') if any(filter.endswith(lookup) for lookup in ('__isnull', '__isempty')): return str_to_bool(value) if any(filter.endswith(lookup) for lookup in ('__hasdict', '__indict')): try: return json_decode(value) except JSONDecodeError: data = {} for subvalue in value.split(','): key, val = subvalue.split(':') data[key] = val return data return value