squint 2024-09-25

Hi folks I hope you all good, does anybody have an example of project using squint with a test suite?

Hey sorry to necro bump this thread back, but I was playing around with tests in the react sample project and my squint.edn file looks like this:

{:paths ["src" "test"]
 :output-dir "public/js"
 :extension "jsx"}
the problem is that all my compiled files are now .jsx and my tests are being compiled public/js folder, is there any config I could do to split up tests vs src ?

maybe an alternative for this would be a way to set different squint.edn files for different tasks

something like: npx squint watch --config squint.test.edn

or with alias, like in tools deps

if you don't want jsx why do you specify it as an extension?

most things are overridable via the command line I think, but let me double check

--paths isn't yet overridable but we could make it so

--extension is

but you could also just not specify it at all in squint.edn

@rafaeldelboni let's start a fresh thread where you introduce the problem at hand

I do have a test suite but it's not a typical test suite...

What platform do you use, browser or node?

mainly browser

I think @martinklepsch has used vitest successfully in his project (right?)

else I would investigate what are the other typical things JS developers use for testing

I think there's even some CLJS people who've used jest

I explored vitest but don't think I went all the way because I wanted to use playwright and support for it was experimental still. But I think you should have pretty good success with the regular vite plugin

which can be as simple as calling compileString

this is specifically a question about testing

or does the regular vite plugin support testing somehow?

I know, since it's vite it's just the same I believe

vitest is basically an assertion lib that integrates with vite, you'll just need to do sth like this

import { expect, test } from 'vitest'
import { sum } from './sum.js'

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3)
})

👍 1

@rafaeldelboni are you looking for unit testing or integration testing?

I do usually both, but honestly a base example with unit tests would be good enough I usually use react-testing-library for more complex integration stuff

trying vitest locally, but I don't understand why it doesn't find my file:

borkdude@m1-3 /tmp/test $ ls test
foo_test.cljs foo_test.mjs
borkdude@m1-3 /tmp/test $ npx vitest

 DEV  v2.1.1 /private/tmp/test

include: **/*.{test,spec}.?(c|m)[jt]s?(x)

No test files found, exiting with code 1

i think the include needs to have .cljs - vite will handle transpilation

I didn't use vite for compilation, I compiled using squint compile to .mjs.

somehow the .mjs file isn't picked up

it doesn’t have the .test.mjs suffix

aah it needs a dot in front of it?

that's a pity since that's not typically what you output from CLJS

so this needs configuring, ah well

that said, you can just compile using vite as well and supply your own include regex

Ah this makes it work with vitest.config.js:

import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    include: ["test/*.mjs"],
  },
})

(ns foo-test
  (:require ["vitest" :refer [expect test]]
            [foo :refer [adder]]))

(test "adder works"
      (fn []
        (-> (expect (adder 1 2 3))
            (.toBe 6))))
Test Files  1 passed (1)
      Tests  1 passed (1)

🆒 1

this misses a key benefit of vitest - it doesn’t compile your cljs

I know, but using squint watch and running npx vitest stuff works good enough for this little test project

watching works

changed the implementation to make it fail and BOOM:

this reminds me of source maps ^^

npx vitest will watch your cljs config if you add the plugin

export default defineConfig({
  plugins: [
    {
      name: "squint_compile",
      transform: function (src, id) {
        if (/\.cljs$/.test(id)) {
          var js = compileString(src);
          return { code: js, map: null };
        }
      },
    }
  ],
});

yes, except that it won't have support for loading namespaces by their namespace name (rather than their file name) and macros. something that still needs to be addressed https://github.com/squint-cljs/vite-plugin-squint/issues/19#issuecomment-2075071784 meanwhile I'm happy to just run npx squint watch in a different window ;)

but yeah, I need to take a look at this once again

Ah yeah, I remember that now!

(also pinged you in the corresponding slack thread, information got decentralized a bit.., but I think we were almost there)

I have a vector of hiccup coming from my server side and would like to render it as #jsx. Something like this, where zz comes from the server as json. I would like to see "hi" but am seeing "phi". Can I render the dynamic vector as react elements somehow?

(defn ViewWork []
  (let [zz [:p "hi"]]
    #jsx [:div zz ]))

No you can’t do this in JSX. The hi element can be dynamic but not the p tag

Unless you make it a another component

Perhaps it works when you prefix the other tag with jsx as well

I tested that in a JSX playground and that seems to work

If I try

(defn ViewWork []
  (let [j [:p "hi"]
        zz #jsx j]
    #jsx [:div [:<> zz] ]))
I get
Uncaught Error: Objects are not valid as a React child (found: object with keys {j1}). If you meant to render a collection of children, use an array instead.

no, (let [j #jsx [:p "hi"] ..)

(defn ViewWork []
  (let [zz #jsx [:p "hi"]]
    #jsx [:div zz ]))

Does that help me with rendering something dynamic from the server?

not unless you dynamically compile this squint code

Maybe I will render on the server and do dangerouslySetInnerHTML

sure you can do that

since you're generating JSX, did you mean to just generate HTML perhaps? or really JSX?

I am just looking to render in my react app a document I have stored as edn on the server side. Generating HTML on the server side using the rum functionality should work for me. Thanks, @borkdude

so the react app is already compiled to JS I assume and you inject some global value in the JS environment which you then want to render?

I call an api which returns a document as json which I want to render. Yes it is an already compiled app.

right. JSX is a compile time feature. This is both true in squint and in React

so creating the HTML on the server and using the "dangerous" feature is probably what you want

Gotcha. I have this working now.