Class RegrasArquitetura

java.lang.Object
br.com.xadm.comum.teste.RegrasArquitetura

public final class RegrasArquitetura extends Object
Fábrica das regras ArchUnit compartilhadas da casa. Cada app monta seu ArchitectureTest com @AnalyzeClasses(packagesOf = Application.class) e compõe estas regras (parametrizadas pelo pacote-base) com as regras próprias da sua topologia — a base não é achatada: só sobe o que é genuinamente comum (plano 003 T3).

Uso:

@ArchTest static final ArchRule importNaoVazio = RegrasArquitetura.importNaoVazio();

@ArchTest static final ArchRule semCiclos =
    RegrasArquitetura.semCiclosEntreFatias("br.com.xadm.meuapp");

Comece pelo importNaoVazio(). As demais regras desta fábrica só valem alguma coisa se o import trouxe classe; sem essa guarda no mesmo ArchitectureTest, herdar as regras é herdar um atestado do nada.

  • Method Summary

    Modifier and Type
    Method
    Description
    static com.tngtech.archunit.lang.ArchRule
    baseNaoDependeDeFatias(String pacoteBase, String motivo, String... pacotesFatia)
    A base transversal não depende de nenhuma das fatias — a forma que o package-by-feature realmente pede.
    static com.tngtech.archunit.lang.ArchRule
    camadaNaoDepende(String pacoteOrigem, String pacoteDestino, String motivo)
    Uma camada não depende de outra (ex.: parsing não depende da camada HTTP).
    static com.tngtech.archunit.lang.ArchRule
    O import do ArchUnit trouxe pelo menos uma classe — a defesa anti-vácuo, que prova que as outras regras rodaram sobre algo.
    static void
    importNaoVazio(com.tngtech.archunit.core.domain.JavaClasses classes)
    Mesma defesa anti-vácuo do importNaoVazio(), na forma de método — para quem prefere o @ArchTest static void (o ArchUnit injeta o parâmetro JavaClasses):
    static com.tngtech.archunit.lang.ArchRule
    Sem ciclos entre as fatias de topo do pacote-base — a invariante que onpetro e vantroba já compartilham (package-by-layer e package-by-feature).

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • importNaoVazio

      public static com.tngtech.archunit.lang.ArchRule importNaoVazio()
      O import do ArchUnit trouxe pelo menos uma classe — a defesa anti-vácuo, que prova que as outras regras rodaram sobre algo.

      Import zerado não é erro no ArchUnit: é descarte silencioso, e toda regra de fronteira passa vácua, verde, testando nada. As duas causas conhecidas:

      • ASM abaixo do piso do JDK — classe num class file major que o ASM bundleado não conhece é pulada no import (Java 25 = major 69 exige ASM ≥ 9.8 / ArchUnit ≥ 1.4.1);
      • @AnalyzeClasses apontando pacote inexistente — tipicamente um rename de pacote que deixou o string-literal para trás.

      Sem esta regra as duas falham para cima: verde. Com ela, falham alto.

      Returns:
      regra ArchUnit que exige ao menos uma classe importada
    • importNaoVazio

      public static void importNaoVazio(com.tngtech.archunit.core.domain.JavaClasses classes)
      Mesma defesa anti-vácuo do importNaoVazio(), na forma de método — para quem prefere o @ArchTest static void (o ArchUnit injeta o parâmetro JavaClasses):
      @ArchTest
      static void importNaoVazio(JavaClasses classes) {
          RegrasArquitetura.importNaoVazio(classes);
      }
      
      Parameters:
      classes - classes importadas pelo @AnalyzeClasses, injetadas pelo ArchUnit
      Throws:
      AssertionError - se o import veio vazio
    • semCiclosEntreFatias

      public static com.tngtech.archunit.lang.ArchRule semCiclosEntreFatias(String pacoteBase)
      Sem ciclos entre as fatias de topo do pacote-base — a invariante que onpetro e vantroba já compartilham (package-by-layer e package-by-feature).
      Parameters:
      pacoteBase - pacote-base do app (ex.: br.com.xadm.meuapp)
      Returns:
      regra ArchUnit de ausência de ciclos entre as fatias de {pacoteBase}.(*)..
    • camadaNaoDepende

      public static com.tngtech.archunit.lang.ArchRule camadaNaoDepende(String pacoteOrigem, String pacoteDestino, String motivo)
      Uma camada não depende de outra (ex.: parsing não depende da camada HTTP).

      Para proibir vários destinos de uma vez (o caso do package-by-feature), use baseNaoDependeDeFatias(String, String, String...) — que rende uma regra, não N.

      Parameters:
      pacoteOrigem - padrão do pacote de origem (ex.: ..processing..)
      pacoteDestino - padrão do pacote proibido como dependência (ex.: ..api..)
      motivo - justificativa (aparece na falha)
      Returns:
      regra ArchUnit proibindo a dependência origem→destino
    • baseNaoDependeDeFatias

      public static com.tngtech.archunit.lang.ArchRule baseNaoDependeDeFatias(String pacoteBase, String motivo, String... pacotesFatia)
      A base transversal não depende de nenhuma das fatias — a forma que o package-by-feature realmente pede.

      É camadaNaoDepende(String, String, String) com N destinos numa regra só: o app com sete features escreveria sete regras, sete nomes e colheria sete falhas para o mesmo defeito. Aqui é uma:

      @ArchTest static final ArchRule comumNaoDependeDeFatias =
          RegrasArquitetura.baseNaoDependeDeFatias(
              "..comum..", "base transversal não conhece feature",
              "..admin..", "..login..", "..deploy..");
      
      Parameters:
      pacoteBase - padrão do pacote da base transversal (ex.: ..comum..)
      motivo - justificativa (aparece na falha)
      pacotesFatia - padrões dos pacotes de feature proibidos; ao menos um
      Returns:
      regra ArchUnit proibindo a base de depender de qualquer uma das fatias
      Throws:
      IllegalArgumentException - se nenhuma fatia for informada — regra sem destino passaria vácua, que é o mesmo falso atestado que o importNaoVazio() combate