clojurescript

2025-05-12T15:42:16.875389Z

i have a macro that returns a call to deftest in clojure, and i'm trying to port it to clojurescript. the issue is that when called from another namespace, i need to have referred clojure.test already (because clojurescript lacks vars).

(ns opticlj.clojure-test
  (:require
   #?(:clj [clojure.test :refer [deftest is]]
      :cljs [clojure.test :refer-macros [deftest is]])
   #?(:clj [opticlj.core :as optic :refer [defoptic]]
      :cljs [opticlj.core :as optic :refer-macros [defoptic]])))

(defmacro defcram
  [test-name & body]
  (let [kw (keyword (str *ns*) (name test-name))]
    `(do (defoptic ~kw [~@body])
         (deftest ~test-name
           (is (optic/check (optic/run ~kw)))))))

thheller 2025-05-12T15:46:52.286189Z

> because clojurescript lacks vars

thheller 2025-05-12T15:47:07.798659Z

is not relevant to this in any way really

😮 1
thheller 2025-05-12T15:47:42.913689Z

things just get a bit confusing sometimes when youre mixing cljs/clj in weird ways

thheller 2025-05-12T15:48:25.309979Z

(ns opticlj.clojure-test
  (:require
    [clojure.test :refer [deftest is]]
    [opticlj.core :as optic :refer [defoptic]]
    ))

thheller 2025-05-12T15:48:59.460589Z

should be all you need. no need for those reader conditional gymnastics

2025-05-12T15:51:01.761309Z

the issue is in opticlj.cram-test:

(ns opticlj.cram-test
  (:require [opticlj.clojure-test :refer [defcram]]))

(defcram example-cram
  (= 6 (+ 3 3)))
produces:
------ WARNING #1 - :undeclared-ns ---------------------------------------------
 File: /Users/noah/personal/opticlj/test/opticlj/cram_test.cljc:4:1
--------------------------------------------------------------------------------
   1 | (ns opticlj.cram-test
   2 |   (:require [opticlj.clojure-test :refer [defcram]]))
   3 |
   4 | (defcram example-cram
-------^------------------------------------------------------------------------
 No such namespace: clojure.test, could not locate clojure/test.cljs, clojure/test.cljc, or JavaScript source providing "clojure.test"
and a bunch more errors

2025-05-12T15:51:22.928999Z

my apologies for not including that initially

thheller 2025-05-12T15:52:58.987309Z

ns opticlj.clojure-test again needs (:require-macros [opticlj.clojure-test])

2025-05-12T15:53:27.349849Z

i tried that, same issue

thheller 2025-05-12T15:54:00.730079Z

with macros using other macros its best to just use fully qualified names

thheller 2025-05-12T15:54:14.513839Z

(defmacro defcram
  [test-name & body]
  (let [kw (keyword (str *ns*) (name test-name))]
    `(do (defoptic ~kw [~@body])
         (clojure.test/deftest ~test-name
           (is (optic/check (optic/run ~kw)))))))

thheller 2025-05-12T15:55:13.482669Z

oh and which shadow-cljs version do you use? a rather long time ago there was a bug where aliasing didn't work

2025-05-12T15:55:31.680009Z

thheller/shadow-cljs {:mvn/version "2.28.21"}

thheller 2025-05-12T15:55:35.039779Z

technically clojure.test doesn't exist in CLJS, it is cljs.test. but there is aliasing in place that should take care of it

thheller 2025-05-12T15:55:40.466999Z

ok thats new enough

thheller 2025-05-12T15:56:18.086889Z

could be that this is a weird edge case that makes the aliasing fail

thheller 2025-05-12T15:56:25.494179Z

if you setup a repro I can take a look

2025-05-12T15:56:50.213519Z

$ npx shadow-cljs compile node-test && node target/shadow-node-test/node-tests.js
shadow-cljs - config: /Users/noah/personal/opticlj/shadow-cljs.edn
shadow-cljs - starting via "clojure"
[:node-test] Compiling ...
[:node-test] Build completed. (171 files, 3 compiled, 4 warnings, 2.51s)

------ WARNING #1 - :undeclared-ns ---------------------------------------------
 File: /Users/noah/personal/opticlj/test/opticlj/cram_test.cljc:4:1
--------------------------------------------------------------------------------
   1 | (ns opticlj.cram-test
   2 |   (:require [opticlj.clojure-test :refer [defcram]]))
   3 |
   4 | (defcram example-cram
-------^------------------------------------------------------------------------
 No such namespace: clojure.test, could not locate clojure/test.cljs, clojure/test.cljc, or JavaScript source providing "clojure.test"
--------------------------------------------------------------------------------
   5 |   (= 6 (+ 3 3)))
   6 |
--------------------------------------------------------------------------------

------ WARNING #2 - :undeclared-var --------------------------------------------
 File: /Users/noah/personal/opticlj/test/opticlj/cram_test.cljc:4:1
--------------------------------------------------------------------------------
   1 | (ns opticlj.cram-test
   2 |   (:require [opticlj.clojure-test :refer [defcram]]))
   3 |
   4 | (defcram example-cram
-------^------------------------------------------------------------------------
 Use of undeclared Var clojure.test/test-var
--------------------------------------------------------------------------------
   5 |   (= 6 (+ 3 3)))
   6 |
--------------------------------------------------------------------------------

------ WARNING #3 - :undeclared-var --------------------------------------------
 File: /Users/noah/personal/opticlj/test/opticlj/cram_test.cljc:4:1
--------------------------------------------------------------------------------
   1 | (ns opticlj.cram-test
   2 |   (:require [opticlj.clojure-test :refer [defcram]]))
   3 |
   4 | (defcram example-cram
-------^------------------------------------------------------------------------
 Use of undeclared Var opticlj.cram-test/java
--------------------------------------------------------------------------------
   5 |   (= 6 (+ 3 3)))
   6 |
--------------------------------------------------------------------------------

------ WARNING #4 - :undeclared-var --------------------------------------------
 File: /Users/noah/personal/opticlj/test/opticlj/cram_test.cljc:4:1
--------------------------------------------------------------------------------
   1 | (ns opticlj.cram-test
   2 |   (:require [opticlj.clojure-test :refer [defcram]]))
   3 |
   4 | (defcram example-cram
-------^------------------------------------------------------------------------
 Use of undeclared Var clojure.test/do-report
--------------------------------------------------------------------------------
   5 |   (= 6 (+ 3 3)))
   6 |
--------------------------------------------------------------------------------

Testing opticlj.cljs.core-test

Testing opticlj.cram-test

ERROR in (example-cram) (ReferenceError:NaN:NaN)
Uncaught exception, not in assertion.
expected: nil
  actual: #object[ReferenceError ReferenceError: java is not defined]

Ran 2 tests containing 2 assertions.
0 failures, 1 errors.

2025-05-12T15:59:47.213529Z

https://github.com/NoahTheDuke/opticlj is the "repro"

2025-05-12T16:00:31.387999Z

i'm running with npx shadow-cljs compile node-test && node target/shadow-node-test/node-tests.js

thheller 2025-05-12T17:03:04.758009Z

I can reproduce but it hurts my head thinking about this. the Use of undeclared Var opticlj.cram-test/java suggests this is expanding the CLJ version of is. which makes sense because at this stage it is in CLJ mode executing a CLJ file

thheller 2025-05-12T17:03:21.839519Z

it works fine if the aliases aren't involved, so just using cljs.test/is and cljs.test/deftest

thheller 2025-05-12T17:03:47.205099Z

the problem is that clojure.test/is actually exists, so the alias doesn't "trigger"

👍 1
2025-05-12T17:17:30.470209Z

thanks for the help