def config_de_la_colección_de_manos_al_contexto(self): @artefacto def miartefacto(c): assert c.mi_clave == "valor" c = Coleccion(miartefacto) c.configurar({"mi_clave": "valor"}) Ejecutor(coleccion=c).ejecutar("miartefacto")
def artefactos_pordefecto_llamados_cuando_no_se_especifican_artefactos(self): # NOTE: cuando no hay artefactos Y no predeterminado, Programa imprimirá # la ayuda global. Simplemente no haremos nada en absoluto, lo cual está # bien por ahora. artefacto = Artefacto(Mock("default-artefacto")) colecc = Coleccion() colecc.ad_artefacto(artefacto, nombre="miartefacto", default=True) ejecutor = Ejecutor(coleccion=colecc) ejecutor.ejecutar() args = artefacto.cuerpo.llamar_args[0] assert isinstance(args[0], Contexto) assert len(args) == 1
def config_de_subcoleccion_funciona_con_artefactos_pordefecto(self): @artefacto(default=True) def miartefacto(c): assert c.mi_clave == "valor" # Configura un artefacto "conocido como" sub.artefacto que puede # ser llamado simplemente 'sub' debido a que es predeterminado. sub = Coleccion("sub", miartefacto=miartefacto) sub.configurar({"mi_clave": "valor"}) principal = Coleccion(sub=sub) # Ejecutar a través de coleccion nombre por defecto 'artefacto'. Ejecutor(coleccion=principal).ejecutar("sub")
def puede_conceder_acceso_al_resultado_delanalisis_del_arg_principal(self): c = AnalizaResultado([AnalizadorDeContexto(nombre="miartefacto")]) e = Ejecutor(coleccion=Coleccion(), nucleo=c) assert e.nucleo is c # prueba de consistenacia del acceso/uso del mundo real assert len(e.nucleo) == 1 assert e.nucleo[0].nombre == "miartefacto" assert len(e.nucleo[0].args) == 0
def artefacto_de_la_mano_con_config_especifica_al_contexto(self): @artefacto def miartefacto(c): assert c.mi_clave == "valor" @artefacto def otroartefacto(c): assert c.mi_clave == "otrovalor" interior1 = Coleccion("interior1", miartefacto) interior1.configurar({"mi_clave": "valor"}) interios2 = Coleccion("interios2", otroartefacto) interios2.configurar({"mi_clave": "otrovalor"}) c = Coleccion(interior1, interios2) e = Ejecutor(coleccion=c) e.ejecutar("interior1.miartefacto", "interios2.otroartefacto")
def setup(self): self.artefacto1 = Artefacto(Mock(valor_de_retorno=7)) self.artefacto2 = Artefacto(Mock(valor_de_retorno=10), pre=[self.artefacto1]) self.artefacto3 = Artefacto(Mock(), pre=[self.artefacto1]) self.artefacto4 = Artefacto(Mock(valor_de_retorno=15), post=[self.artefacto1]) self.contextualizado = Artefacto(Mock()) colecc = Coleccion() colecc.ad_artefacto(self.artefacto1, nombre="artefacto1") colecc.ad_artefacto(self.artefacto2, nombre="artefacto2") colecc.ad_artefacto(self.artefacto3, nombre="artefacto3") colecc.ad_artefacto(self.artefacto4, nombre="artefacto4") colecc.ad_artefacto(self.contextualizado, nombre="contextualizado") self.ejecutor = Ejecutor(coleccion=colecc)
def llamadas_pordefecto_a_args_vacios_siempre(self): pre_cuerpo, post_cuerpo = Mock(), Mock() t1 = Artefacto(pre_cuerpo) t2 = Artefacto(post_cuerpo) t3 = Artefacto(Mock(), pre=[t1], post=[t2]) e = Ejecutor(coleccion=Coleccion(t1=t1, t2=t2, t3=t3)) e.ejecutar(("t3", {"algo": "bah"})) for cuerpo in (pre_cuerpo, post_cuerpo): args = cuerpo.llamar_args[0] assert len(args) == 1 assert isinstance(args[0], Contexto)
def desduplicacion_trata_diferentes_llamadas_al_mismo_artefacto_de_manera_diferente(self): cuerpo = Mock() t1 = Artefacto(cuerpo) pre = [llamar(t1, 5), llamar(t1, 7), llamar(t1, 5)] t2 = Artefacto(Mock(), pre=pre) c = Coleccion(t1=t1, t2=t2) e = Ejecutor(coleccion=c) e.ejecutar("t2") # No llama al segundo t1(5) lista_de_parametros = [] for llamada_al_cuerpo in cuerpo.llamada_a_lista_de_args: assert isinstance(llamada_al_cuerpo[0][0], Contexto) lista_de_parametros.append(llamada_al_cuerpo[0][1]) assert set(lista_de_parametros) == {5, 7}
def la_eliminacion_de_la_config_se_conserva_entre_artefactos(self): @artefacto def artefacto1(c): del c.config.correr.echo # NOTE: devuelto para inspección de prueba, ¡no como # mecanismo para compartir datos! return c @artefacto def artefacto2(c): return c colecc = Coleccion(artefacto1, artefacto2) ret = Ejecutor(coleccion=colecc).ejecutar("artefacto1", "artefacto2") c2 = ret[artefacto2] assert "echo" not in c2.config.correr
def nuevos_datos_de_config_se_conservan_entre_artefactos(self): @artefacto def artefacto1(c): c.foo = "bar" # NOTE: Devuelto para la inspección de prueba, no como # mecanismo de compartir datos! return c @artefacto def artefacto2(c): return c colecc = Coleccion(artefacto1, artefacto2) ret = Ejecutor(coleccion=colecc).ejecutar("artefacto1", "artefacto2") c2 = ret[artefacto2] assert "foo" in c2.config assert c2.foo == "bar"
def contexto_es_nuevo_pero_la_config_es_la_misma(self): @artefacto def artefacto1(c): return c @artefacto def artefacto2(c): return c colecc = Coleccion(artefacto1, artefacto2) ret = Ejecutor(coleccion=colecc).ejecutar("artefacto1", "artefacto2") c1 = ret[artefacto1] c2 = ret[artefacto2] assert c1 is not c2 # TODO: eventualmente, es posible que deseemos cambiar esto # nuevamente, siempre que los valores efectivos dentro de la # configuración sigan coincidiendo ...? Ehh assert c1.config is c2.config
def _llamar_objs(self): # Setup pre_cuerpo, post_cuerpo = Mock(), Mock() t1 = Artefacto(pre_cuerpo) t2 = Artefacto(post_cuerpo) t3 = Artefacto( Mock(), pre=[llamar(t1, 5, foo="bar")], post=[llamar(t2, 7, biz="baz")], ) c = Coleccion(t1=t1, t2=t2, t3=t3) e = Ejecutor(coleccion=c) e.ejecutar("t3") # Pre-artefacto asserts args, kwargs = pre_cuerpo.llamar_args assert kwargs == {"foo": "bar"} assert isinstance(args[0], Contexto) assert args[1] == 5 # Post-artefacto asserts args, kwargs = post_cuerpo.llamar_args assert kwargs == {"biz": "baz"} assert isinstance(args[0], Contexto) assert args[1] == 7
def el_resultado_del_análisis_del_arg_nucleo_establece_pordefecto_None(self): assert Ejecutor(coleccion=Coleccion()).nucleo is None
from dued import Coleccion, artefacto, llamar from paquete import modulo @artefacto def top_pre(c): pass @artefacto(llamar(top_pre)) def altonivel(c): pass hng = Coleccion(modulo, altonivel)
def usa_config_en_blanco_de_forma_predeterminada(self): e = Ejecutor(coleccion=Coleccion()) assert isinstance(e.config, Config)
"Artefactos para compilar código estático y activos." from dued import artefacto, Coleccion from . import docs, python @artefacto(nombre="all", alias=["all"], default=True) def all_(c): "Fabrica los artefactos necesarios." pass @artefacto(alias=["ext"]) def c_ext(c): "Construye nuestra extensión C interna." pass @artefacto def zap(c): "Una forma majadera de limpiar." pass hng = Coleccion(all_, c_ext, zap, docs, python)
from dued import cartefacto, Coleccion @cartefacto def go(c): c.correr("false") # Ensures a kaboom if mocking fails hng = Coleccion(go) hng.configurar({"correr": {"echo": True}})
Número de trabajos a correr, en total. Idealmente, número de CPUs. """ os.chdir("integracion/_soporte") cmd = "seq {} | parallel -n0 --halt=now,fail=1 du -c regresion chequeo" c.correr(cmd.format(jobs)) # hng = Espacio de nombres hng = Coleccion( prueba, cobertura, integracion, regresion, vendorize, release, # www, # docs, # sites, # watch_docs, travis, checks.blacken, ) hng.configurar({ "blacken": { # Sáltate el directorio de vendor y la venv alternativa # (sólo para Travis) cuando te blackeneas. # TODO: esto hace que parezca que realmente quiero un explícito # arg/conf-opt en el blacken artefacto para "rutas excluidos"...ha "find_opts": "-and -not \( -ruta './dued/vendor*' -or -ruta './alt_entorno*' -or -ruta './fabricar*' \)" # noqa },
from dued import artefacto, Coleccion @artefacto def altonivel(c): pass @artefacto def subartefacto(c): pass hng = Coleccion( altonivel, Coleccion("a", subartefacto, Coleccion("otracosa", subartefacto)) )
from dued import artefacto, Coleccion from . import fabric, desplegar, provision @artefacto(alias=["termIA"]) def iterminal(c): "Carga REPL con estado y config. de Py." pass @artefacto(alias=["correr_pruebas"], default=True) def prueba(c): "Corre suite prueba respaldada en args." pass # NOTE: using fabric's internal coleccion directly as a way of ensuring a # corner case (coleccion 'named' via local kwarg) gets tested for --lista. # NOTE: Docstring cloning in effect to preserve the final organic looking # resultado... localbuild = fabric.hng localbuild.__doc__ = fabric.__doc__ hng = Coleccion(iterminal, prueba, desplegar, provision, fabric=localbuild)
def _carga(self, nombre): mod, _ = self.cargador.cargar(nombre) return Coleccion.del_modulo(mod)
from dued import artefacto, Coleccion @artefacto def miartefacto(c): assert c.exterior.interior.hurra == "yml" hng = Coleccion(miartefacto)
from dued import artefacto, Coleccion @artefacto def dummy(c): pass hng = Coleccion(dummy, Coleccion("subcoleccion"))
def reconocer_coleccion_y_config(self): colecc = Coleccion() conf = Config() e = Ejecutor(coleccion=colecc, config=conf) assert e.coleccion is colecc assert e.config is conf
from dued import artefacto, Coleccion @artefacto def z_altonivel(c): pass @artefacto def subartefacto(c): pass hng = Coleccion(z_altonivel, Coleccion("a", Coleccion("b", subartefacto)))
""" LETRAS EXPLICITAS """ from dued import artefacto, Coleccion @artefacto(alias=["otro_alto"]) def alto_nivel(c): pass @artefacto(alias=["otro_sub"], default=True) def sub_artefacto(c): pass sub = Coleccion("sub_nivel", sub_artefacto) hng = Coleccion(alto_nivel, sub)