class DoorNumberValueTest(unittest.TestCase): def setUp(self): self.parser = AddressParser() def test_int_door_number_value(self): """Una dirección con altura numérica en forma de número entero debería retornar tipo int en 'normalized_door_number_value()'.""" data = self.parser.parse('Callao 1231') self.assertEqual(data.normalized_door_number_value(), 1231) def test_float_door_number_value_comma(self): """Una dirección con altura numérica en forma de número decimal debería retornar tipo float en 'normalized_door_number_value()' (con coma).""" data = self.parser.parse('Ruta provincial 4 km 32,5') self.assertAlmostEqual(data.normalized_door_number_value(), 32.5) def test_float_door_number_value_point(self): """Una dirección con altura numérica en forma de número decimal debería retornar tipo float en 'normalized_door_number_value()' (con punto).""" data = self.parser.parse('Ruta provincial 4 km 32.5') self.assertAlmostEqual(data.normalized_door_number_value(), 32.5) def test_none_door_number_value(self): """Una dirección sin valor numérico debería retornar 'None' en 'normalized_door_number_value()'.""" data = self.parser.parse('Leandro Alem S/N') self.assertIsNone(data.normalized_door_number_value())
class InvalidAddressesParserTest(unittest.TestCase): def setUp(self): self.parser = AddressParser() def test_empty_address(self): """Un string vacío como dirección debería resultar en None.""" data = self.parser.parse('') self.assertIsNone(data) def test_ambiguous_address(self): """Una dirección ambigua debería resultar en None.""" data = self.parser.parse('Tucumán y Córdoba y Callao') self.assertIsNone(data)
def test_address_parser_cache_same_structures(self): """Al utilizar un cache, y si dos direcciones comparten la misma estructura, solo se debería agregar una key para las dos.""" cache = {} parser = AddressParser(cache=cache) addresses = [ 'Corrientes 1000', 'Tucumán 2000', 'Córdoba 3333' ] for address in addresses: parser.parse(address) self.assertEqual(len(cache), 1)
def test_address_parser_cache(self): """Al utilizar un cache, se debería agregar una key por cada esctructura de dirección distinta.""" cache = {} parser = AddressParser(cache=cache) addresses = [ 'Corrientes 1000', 'Santa fe 2000', 'callle 10 123 y Tucumán' ] for address in addresses: parser.parse(address) self.assertEqual(len(cache), len(addresses))
class AddressParameter(Parameter): """Representa un parámetro de tipo dirección de calle (nombre y altura). Se heredan las propiedades y métodos de la clase Parameter, definiendo nuevamente el método '_parse_value' para implementar lógica de parseo y validación propias de AddressParameter. Attributes: _parser (AddressParser): Parser de direcciones de la librería georef-ar-address. _parser_lock (threading.Lock): Mutex utilizado para sincronizar el uso de '_parser' (ver comentario en '__init__'). """ def __init__(self): # Se crea el Lock 'self._parser_lock' para evitar problemas con # 'self._parser' en contextos de ejecución donde se usen threads, ya # que el parser cuenta con un estado interno mutable (su propiedad # '_cache'). Si se utilizan threads o no depende de la configuración # que se esté usando para los workers de Gunicorn. Por defecto los # workers son de tipo 'sync', por lo que se crea un proceso separado # por worker (no se usan threads). self._parser_lock = threading.Lock() cache = utils.LFUDict(constants.ADDRESS_PARSER_CACHE_SIZE) self._parser = AddressParser(cache=cache) super().__init__(required=True) def _parse_value(self, val): if not val: raise ValueError(strings.STRING_EMPTY) with self._parser_lock: return self._parser.parse(val)
class DoorNumberUnitTest(unittest.TestCase): def setUp(self): self.parser = AddressParser() def test_int_door_number_unit_none(self): """Una dirección con altura sin prefijo debería devolver None en 'normalized_door_number_unit()'.""" data = self.parser.parse('Callao 1231') self.assertIsNone(data.normalized_door_number_unit()) def test_int_door_number_unit_none_n(self): """Una dirección con altura sin prefijo 'N' debería devolver None en 'normalized_door_number_unit()'.""" data = self.parser.parse('Callao N 1231') self.assertIsNone(data.normalized_door_number_unit()) def test_int_door_number_unit_km(self): """Una dirección con altura sin prefijo 'KM.' debería devolver 'km' en 'normalized_door_number_unit()'.""" data = self.parser.parse('Ruta 33 KM. 33') self.assertEqual(data.normalized_door_number_unit(), 'km')