def se_filtra_a_los_nombres_de_las_subcolecciones(self): @artefacto def mi_artefacto(c): pass colecc = Coleccion(interior_colecc=Coleccion(mi_artefacto)) contextos = colecc.a_contextos() assert contextos[0].nombre == "interior-colecc.mi-artefacto"
def arglista_posicional_preserva_el_orden_dado(self): @artefacto(posicional=("segundo", "primero")) def miartefacto(c, primero, segundo, third): pass colecc = Coleccion() colecc.ad_artefacto(miartefacto) c = colecc.a_contextos()[0] esperado = [c.args["segundo"], c.args["primero"]] assert c.args_posicionales == esperado
def setup(self): # Contexto normal, no relacionado con artefacto/colección self.ordinario = Contexto( args=(Argumento("foo"), Argumento("bar", help="bar el baz"))) # Artefacto/Colección Contexto generado # (expondrá banderas n tales) @artefacto(help={"otroarg": "otra ayuda"}, opcional=["valopc"]) def miartefacto(c, miarg, otroarg, valopc, intval=5): pass col = Coleccion(miartefacto) self.tasked = col.a_contextos()[0]
def se_filtra_a_artefactos_de_subcoleccion(self): @artefacto def artefacto_externo(c): pass @artefacto def artefacto_interno(c): pass colecc = Coleccion(artefacto_externo, interior=Coleccion(artefacto_interno)) contextos = colecc.a_contextos() esperado = { "artefacto-exterior", "interior.interior-artefacto" } assert {x.nombre for x in contextos} == esperado
class AnalisisCLI: """ Pruebas de análisis de alto nivel """ def setup(self): @artefacto(posicional=[], iterable=["mi_lista"], incremento=["verbose"]) def mi_artefacto( c, micadena, s, booleano=False, b=False, v=False, nombre_largo=False, bool_true=True, _guionbajo_principal=False, guionbajo_posterior=False, mi_lista=None, verbose=0, ): pass @artefacto(alias=["mi_artefacto27"]) def mi_artefacto2(c): pass @artefacto(default=True) def mi_artefacto3(c, micadena): pass @artefacto def mi_artefacto4(c, limpiar=False, browse=False): pass @artefacto(alias=["otro"], default=True) def sub_artefacto(c): pass sub_colecc = Coleccion("sub_colecc", sub_artefacto) self.c = Coleccion(mi_artefacto, mi_artefacto2, mi_artefacto3, mi_artefacto4, sub_colecc) def _analizador(self): return Analizador(self.c.a_contextos()) def _analizar(self, argstr): return self._analizador().analizar_args(argstr.split()) def _comparar(self, dued, banderaname, valor): dued = "mi-artefacto " + dued resultado = self._analizar(dued) assert resultado[0].args[banderaname].valor == valor def _comparar_nombres(self, dado, real): assert self._analizar(dado)[0].nombre == real def banderas_guinesbajos_se_pueden_dar_como_discontinuas(self): self._comparar("--nombre-largo", "nombre_largo", True) def guionesbajos_iniciales_son_ignorados(self): self._comparar("--guionbajo-principal", "_guionbajo_principal", True) def guinesbajos_posteriores_se_ignoran(self): self._comparar("--guionbajo-posterior", "guionbajo_posterior", True) def banderas_booleanas_inversas(self): self._comparar("--bool-no-es-true", "bool_true", False) def espaciodenombre_de_artefacto(self): self._comparar_nombres("sub-colecc.sub-artefacto", "sub-colecc.sub-artefacto") def alias(self): self._comparar_nombres("mi-artefacto27", "mi-artefacto2") def alias_de_subcoleccion(self): self._comparar_nombres("sub-colecc.otro", "sub-colecc.sub-artefacto") def subcoleccion_de_artefactos_pordefecto(self): self._comparar_nombres("sub-colecc", "sub-colecc.sub-artefacto") def args_booleano(self): "mi-artefacto --booleano" self._comparar("--booleano", "booleano", True) def bandera_luego_espacio_luego_valor(self): "mi-artefacto --micadena foo" self._comparar("--micadena foo", "micadena", "foo") def bandera_luego_signo_igual_luego_valor(self): "mi-artefacto --micadena=foo" self._comparar("--micadena=foo", "micadena", "foo") def bandera_booleana_corta(self): "mi-artefacto -b" self._comparar("-b", "b", True) def bandera_corta_luego_espacio_luego_valor(self): "mi-artefacto -s valor" self._comparar("-s valor", "s", "valor") def bandera_corta_luego_signo_igual_luego_valor(self): "mi-artefacto -s=valor" self._comparar("-s=valor", "s", "valor") def bandera_corta_con_valor_adyacente(self): "mi-artefacto -svalue" r = self._analizar("mi-artefacto -svalue") assert r[0].args.s.valor == "valor" def _bandera_valor_artefacto(self, valor): r = self._analizar("mi-artefacto -s {} mi-artefacto2".format(valor)) assert len(r) == 2 assert r[0].nombre == "mi-artefacto" assert r[0].args.s.valor == valor assert r[1].nombre == "mi-artefacto2" def bandera_valor_luego_artefacto(self): "mi-artefacto -s valor mi-artefacto2" self._bandera_valor_artefacto("valor") def bandera_valor_igual_que_el_nombre_del_artefacto(self): "mi-artefacto -s mi-artefacto2 mi-artefacto2" self._bandera_valor_artefacto("mi-artefacto2") def tres_artefactos_con_args(self): "mi-artefacto --booleano mi-artefacto3 --micadena foo mi-artefacto2" r = self._analizar( "mi-artefacto --booleano mi-artefacto3 --micadena foo mi-artefacto2" ) assert len(r) == 3 assert [x.nombre for x in r ] == ["mi-artefacto", "mi-artefacto3", "mi-artefacto2"] assert r[0].args.booleano.valor assert r[1].args.micadena.valor == "foo" def artefactos_con_kwargs_con_nombre_duplicado(self): "mi-artefacto --micadena foo mi-artefacto3 --micadena bar" r = self._analizar( "mi-artefacto --micadena foo mi-artefacto3 --micadena bar") assert r[0].nombre == "mi-artefacto" assert r[0].args.micadena.valor == "foo" assert r[1].nombre == "mi-artefacto3" assert r[1].args.micadena.valor == "bar" def múltiples_banderas_cortas_adyacentes(self): "mi-artefacto -bv (e inversas)" for args in ("-bv", "-vb"): r = self._analizar("mi-artefacto {}".format(args)) a = r[0].args assert a.b.valor assert a.v.valor def bandera_tipo_lista_se_puede_dar_N_veces_construyendo_una_lista(self): "mi-artefacto --mi-lista foo --mi-lista bar" # Probe tanto el singular como el plural, solo para estar seguro. self._comparar("--mi-lista foo", "mi-lista", ["foo"]) self._comparar("--mi-lista foo --mi-lista bar", "mi-lista", ["foo", "bar"]) def bandera_tipo_incrementable_se_puede_usar_como_interruptor_o_contador( self): "mi-artefacto -v, -vv, -vvvvv etc, excepto con explicito --verbose" self._comparar("", "verbose", 0) self._comparar("--verbose", "verbose", 1) self._comparar("--verbose --verbose --verbose", "verbose", 3)
class a_contextos: def setup(self): @artefacto def miartefacto(c, texto, booleano=False, number=5): print(texto) @artefacto(alias=["miartefacto27"]) def miartefacto2(c): pass @artefacto(alias=["otroartefacto"], default=True) def subartefacto(c): pass sub = Coleccion("sub", subartefacto) self.c = Coleccion(miartefacto, miartefacto2, sub) self.contextos = self.c.a_contextos() alias_tups = [list(x.alias) for x in self.contextos] self.alias = reduce(operator.add, alias_tups, []) # Focus on 'miartefacto' as it has the more interesting sig self.contexto = [ x for x in self.contextos if x.nombre == "miartefacto" ][0] def devuelve_iterable_de_Contextos_correspondientes_a_artefactos(self): assert self.contexto.nombre == "miartefacto" assert len(self.contextos) == 3 class nombre_auto_guion: def nombres_de_contexto_se_vuelven_discontinuos_automaticamente( self): @artefacto def mi_artefacto(c): pass contextos = Coleccion(mi_artefacto).a_contextos() assert contextos[0].nombre == "mi-artefacto" def se_filtra_a_artefactos_de_subcoleccion(self): @artefacto def artefacto_externo(c): pass @artefacto def artefacto_interno(c): pass colecc = Coleccion(artefacto_externo, interior=Coleccion(artefacto_interno)) contextos = colecc.a_contextos() esperado = { "artefacto-exterior", "interior.interior-artefacto" } assert {x.nombre for x in contextos} == esperado def se_filtra_a_los_nombres_de_las_subcolecciones(self): @artefacto def mi_artefacto(c): pass colecc = Coleccion(interior_colecc=Coleccion(mi_artefacto)) contextos = colecc.a_contextos() assert contextos[0].nombre == "interior-colecc.mi-artefacto" def los_alias_tambien_estan_discontinuos(self): @artefacto(alias=["hola_estoy_subguionado"]) def cualquier(c): pass contextos = Coleccion(cualquier).a_contextos() assert "hola-estoy-subguionado" in contextos[0].alias def los_guiones_bajos_iniciales_y_finales_no_se_ven_afectados( self): @artefacto def _lo_que_siempre_(c): pass @artefacto def _enfriador_interior_(c): pass interior = Coleccion("interior", _enfriador_interior_) contextos = Coleccion(_lo_que_siempre_, interior).a_contextos() esperado = { "_lo_que-siempre_", "interior._enfriador-interior_" } assert {x.nombre for x in contextos} == esperado def _guiones_bajos_anidados(self, nombre_auto_guion=None): @artefacto(alias=["otro_nombre"]) def mi_artefacto(c): pass @artefacto(alias=["otro_interior"]) def artefacto_interno(c): pass # NOTE: explícitamente no dar kwarg a la subcolección; esto # prueba que el espacio de nombres de nivel superior realiza # la transformación inversa cuando es necesario. sub = Coleccion("interior_colecc", artefacto_interno) return Coleccion(mi_artefacto, sub, nombre_auto_guion=nombre_auto_guion) def honra_el_seteo_de_inicio_en_el_hng_superior(self): colecc = self._guiones_bajos_anidados(nombre_auto_guion=False) contextos = colecc.a_contextos() nombres = ["mi_artefacto", "interior_colecc.artefacto_interno"] alias = [["otro_nombre"], ["interior_colecc.otro_interior"]] assert sorted(x.nombre for x in contextos) == sorted(nombres) assert sorted(x.alias for x in contextos) == sorted(alias) def las_transformaciones_se_aplican_a_en_de_modulos_explícitos( self): # Síntoma cuando hay un error: Coleccion.a_contextos() muere # porque itera sobre .nombres_de_artefactos (transformado) y # luego intenta usar resultado para acceder a __getitem__ # (sin transformación automática ... porque en todas las demás # situaciones, las claves de estructura de artefacto ya están # transformadas; ¡pero este no fue el caso de del_modulo() con # objetos explícitos 'hng'!) hangar = self._guiones_bajos_anidados() class FakeModule(object): __name__ = "mi_modulo" hng = hangar colecc = Coleccion.del_modulo(FakeModule(), nombre_auto_guion=False) # NOTE: underscores, not dashes esperado = { "mi_artefacto", "interior_colecc.artefacto_interno" } assert {x.nombre for x in colecc.a_contextos()} == esperado def permite_el_acceso_tipobandera_via_banderas(self): assert "--texto" in self.contexto.banderas def arglista_posicional_preserva_el_orden_dado(self): @artefacto(posicional=("segundo", "primero")) def miartefacto(c, primero, segundo, third): pass colecc = Coleccion() colecc.ad_artefacto(miartefacto) c = colecc.a_contextos()[0] esperado = [c.args["segundo"], c.args["primero"]] assert c.args_posicionales == esperado def expone_nombres_de_artefactos_con_EN(self): assert "sub.subartefacto" in [x.nombre for x in self.contextos] def expone_alias_de_artefactos_con_EN(self): assert "sub.otroartefacto" in self.alias def expone_los_artefactos_pordefecto_de_la_subcoleccion(self): assert "sub" in self.alias def expone_alias(self): assert "miartefacto27" in self.alias