4

I have been inspired buy this book: Building Evolutionary Architectures and clean architecture.

One of the concept is to be able to test your architecture in the code. In particular I would like to be able to check dependencies between namespaces, layers and assert that a namespace doesn't call a namespace for another layer.

All my namespaces are inside the circles:

my architecture

The idea is that a namespace inside 'controllers' can not import a namespace inside 'entities' but only import namespaces below him (use-cases). And I would like to detect this in my unit tests.

So this should fail in my unit tests:

(ns com.controller.core
  (:require [com.entities.core :as entities]
            [com.use-cases.core :as use-cases]))

(defn do-something [args]
      (let [use-cases-results (use-cases/do-something args)]
           (entities/do-some-other-thing use-cases-results)))

In java you can write those sort of unit tests using archunit.

private final JavaClasses classes = new ClassFileImporter().importPackagesOf(Controller/core.class);

noClasses().that().resideInAPackage("..controller..").should().accessClassesThat().resideInAPackage("..use-cases..").check(classes);

Are you using something similar for clojure or do you have some suggestions how to tackle this problem?

5
  • 2
    This is a perfectly valid and interesting question but some of the nitpickers would like to see more concrete detail. Could you add a brief example- a little sample code with 2 or 3 namespaces, and some references between them, and an example of the kind of test shape you would like to see fail given the example? Commented May 23, 2018 at 16:34
  • 2
    BTW, here's a good fairly recent list of code quality tools: blog.jeaye.com/2017/08/31/clojure-code-quality. There also is a legendary old project from Rich Hickey, the author of Clojure, called codeq: github.com/Datomic/codeq which loads a git repo into a Datomic database, allowing for various kinds of code shape queries. Rumors are that Cognitect will be giving codeq some love in the near future. Commented May 23, 2018 at 16:36
  • 2
    One more reference- there is an interesting project written in Clojure that focuses on code quality and deeper tech and architectural debt issues, see here: clojure.org/stories/empear. The founder is author of a great code analysis book "Code as a Crime Scene", see adamtornhill.com for more Commented May 23, 2018 at 16:47
  • codeq is really cool! but for may case I would like to have something like archunit :) Commented May 24, 2018 at 9:19
  • I am looking for exactly the same. I think Clojure core provides the tools to achieve this, and there are libraries in this space too focusing on static analysis. It's a shame that a wonderful language, used in cautiously, can still yield a mess when everything is globally referenceable. Enforcing structures is a good way of stopping this happening. Commented Dec 11, 2020 at 9:35

1 Answer 1

0

How about using ns-refers something like:

(deftest controllers-should-not-refer-to-entities
  (is (->> (all-ns)
           (filter #(clojure.string/includes? % "controller"))
           (map ns-refers)
           (map vals)
           flatten
           (not-any? #(clojure.string/includes? % "entities")))))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.