clj-kondo

2024-08-22T08:13:44.761439Z

yesterday I noticed an issue with our tests where, we had something like

(deftest mytest
 ...
 (fn [{:keys [v]}]
   (is (= 1 1))))
which meant that the the assertion was never actually checked. It happened because previously there was a function that took another function just above and a refactoring messed it up. I guess clj-kondo can't detect these sorts of mistakes right?

borkdude 2024-08-22T09:49:43.374219Z

There is a check like this but this specific case might not be covered yet. It’s called missing test assertion

borkdude 2024-08-22T09:49:48.540779Z

Issue welcome

2024-08-22T10:01:27.217649Z

yeah I was wondering if it's technically possible at all

2024-08-22T10:02:03.776219Z

since it would have to know that the macro/function just above is not actually eventually executing that function passed in

borkdude 2024-08-22T10:23:23.979619Z

I think a top level function should be reported as an unused value like in defn

2024-08-22T10:25:53.147459Z

I mean something like this should not be considered invalid for example, where with-infra can either be a function or a macro

(with-infra
  (fn [k]
    (is (= 1 ...))

borkdude 2024-08-22T10:26:23.293149Z

Sure but deftest is known to be not like that

2024-08-22T13:46:33.246269Z

yeah but we have this sort of code inside a deftest for example

2024-08-22T13:47:18.814419Z

I don't think you can tell from static analysis if a macro/function would call the function it takes as argument right?

borkdude 2024-08-22T15:40:33.657239Z

Please give a complete example because I think we're misunderstanding. The example you gave:

(deftest mytest
 ...
 (fn [{:keys [v]}]
   (is (= 1 1))))
indicates that the fn is placed as a top level expression inside deftest but the explanations that follow make it seem that this is not the case. So a complete example would get rid of that ambiguity

2024-08-22T15:57:05.544579Z

ah yeah well it would not be under deftest directly

2024-08-22T15:57:21.321439Z

iI mean yeah if it is then yeah it's possible to detect

2024-08-22T15:57:34.356799Z

but I think it would not be in our code at least

borkdude 2024-08-22T16:03:04.471489Z

yeah, in that case it's quite impossible

yuhan 2024-08-22T23:57:06.995489Z

Is there a way to suppress the unused-binding linter specifically for the initial argument in a defrecord/extend-type/extend-protocol method arglist?

(defrecord Foo [bar]
  Bazzable
  (baz [this] bar)) ;; <- Warning: unused binding this

yuhan 2024-08-22T23:58:52.287659Z

One could go about naming them with a leading underscore _this /`_ but that doesn't seem very idiomatic.. after all it is being used implicitly by the field references bar` ~ (.-bar this)

borkdude 2024-08-23T05:53:44.974659Z

perhaps we should make this an option , issue welcome

👍 1
Stig Brautaset 2024-08-23T10:07:09.183989Z

We use this in some code:

{:linters {:unused-binding {:exclude-patterns ["^this"]}}}

➕ 1
Stig Brautaset 2024-08-23T10:09:37.415459Z

That's not specific for the first parameter of defrecord et. al, but it seems to work for us.

borkdude 2024-08-23T10:20:12.674939Z

Ah yes, that’s a good solution as well