diff --git a/.clj-kondo/imports/babashka/fs/babashka/fs.clj_kondo b/.clj-kondo/imports/babashka/fs/babashka/fs.clj_kondo new file mode 100644 index 00000000..73d44096 --- /dev/null +++ b/.clj-kondo/imports/babashka/fs/babashka/fs.clj_kondo @@ -0,0 +1,36 @@ +(ns babashka.fs + (:require [clj-kondo.hooks-api :as api])) + +(defn- symbol-node? [node] + (and (api/token-node? node) + (symbol? (api/sexpr node)))) + +(defn with-temp-dir + [{:keys [node]}] + (let [args (rest (:children node)) + binding-like-vector (first args) + body (rest args)] + (when-not (zero? (count args)) ;; let clj-kondo report on arity + (if-not (api/vector-node? binding-like-vector) + (api/reg-finding! (assoc (meta binding-like-vector) + :message "babashka.fs/with-temp-dir requires a vector for first arg" + :type :babashka-fs/with-temp-dir-first-arg-not-vector)) + (let [[binding-sym options & rest-in-vec] (:children binding-like-vector)] + (when (not (symbol-node? binding-sym)) + (api/reg-finding! (assoc (meta (or binding-sym binding-like-vector)) + :message "babashka.fs/with-temp-dir vector arg requires binding-name symbol as first value" + :type :babashka-fs/with-temp-dir-vector-arg-needs-binding-symbol))) + (doseq [extra-vector-arg rest-in-vec] + (api/reg-finding! (assoc (meta extra-vector-arg) + :message "babashka.fs/with-temp-dir vector arg accepts at most 2 values" + :type :babashka-fs/with-temp-dir-vector-arg-extra-value))) + + (when binding-sym + {:node (api/list-node + ;; satisfy linter by creating binding for for binding-sym + (list* + (api/token-node 'let) + ;; it doesn't really matter what we bind to, so long as it is bound + (api/vector-node [binding-sym (api/token-node nil)]) + options ;; avoid unused binding when options is a binding + body))})))))) diff --git a/.clj-kondo/imports/babashka/fs/config.edn b/.clj-kondo/imports/babashka/fs/config.edn index 23f36094..026ca7ed 100644 --- a/.clj-kondo/imports/babashka/fs/config.edn +++ b/.clj-kondo/imports/babashka/fs/config.edn @@ -1 +1,4 @@ -{:lint-as {babashka.fs/with-temp-dir clojure.core/let}} +{:linters {:babashka-fs/with-temp-dir-first-arg-not-vector {:level :error} + :babashka-fs/with-temp-dir-vector-arg-needs-binding-symbol {:level :error} + :babashka-fs/with-temp-dir-vector-arg-extra-value {:level :error}} + :hooks {:analyze-call {babashka.fs/with-temp-dir babashka.fs/with-temp-dir}}} diff --git a/.clj-kondo/imports/nubank/matcher-combinators/config.edn b/.clj-kondo/imports/nubank/matcher-combinators/config.edn new file mode 100644 index 00000000..ea4ded72 --- /dev/null +++ b/.clj-kondo/imports/nubank/matcher-combinators/config.edn @@ -0,0 +1,4 @@ +{:linters + {:unresolved-symbol + {:exclude [(cljs.test/is [match? thrown-match?]) + (clojure.test/is [match? thrown-match?])]}}} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 12fd48cb..dc8e0bb8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup uses: ./.github/workflows/shared-setup diff --git a/.github/workflows/shared-setup/action.yml b/.github/workflows/shared-setup/action.yml index 5f47302f..f7410430 100644 --- a/.github/workflows/shared-setup/action.yml +++ b/.github/workflows/shared-setup/action.yml @@ -14,7 +14,7 @@ runs: steps: - name: Clojure deps cache - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | ~/.m2/repository diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a38f379e..c9d989c5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup uses: ./.github/workflows/shared-setup @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup uses: ./.github/workflows/shared-setup @@ -58,7 +58,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup uses: ./.github/workflows/shared-setup diff --git a/.gitignore b/.gitignore index 4ec1b8b1..f4100127 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ aws.clj .cpcache .idea *.iml +.nrepl-port diff --git a/bb.edn b/bb.edn index d8b4e659..e9d4fbf8 100644 --- a/bb.edn +++ b/bb.edn @@ -28,7 +28,8 @@ {:doc "Runs tests under babashka Clojure (recognizes cognitect test-runner args)" :extra-paths ["src" "test" "test-resources"] :extra-deps {io.github.cognitect-labs/test-runner - {:git/tag "v0.5.1" :git/sha "dfb30dd"}} + {:git/tag "v0.5.1" :git/sha "dfb30dd"} + nubank/matcher-combinators {:mvn/version "3.9.2"}} :requires ([cognitect.test-runner :as tr]) :task (apply tr/-main *command-line-args*)} lint diff --git a/deps.edn b/deps.edn index 3e9a4559..026ef23a 100644 --- a/deps.edn +++ b/deps.edn @@ -9,18 +9,18 @@ :1.9 {:override-deps {org.clojure/clojure {:mvn/version "1.9.0"}}} :1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.3"}}} :1.11 {:override-deps {org.clojure/clojure {:mvn/version "1.11.4"}}} - :1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.3"}}} + :1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.4"}}} :build {:extra-paths ["build"] - :deps {io.github.clojure/tools.build {:mvn/version "0.10.10"} + :deps {io.github.clojure/tools.build {:mvn/version "0.10.11"} slipset/deps-deploy {:mvn/version "0.2.2"}} :ns-default build} :http-server ;; used for to support integration tests {:extra-paths ["test" "test-resources"] :override-deps {org.clojure/clojure {:mvn/version "1.12.3"}} - :extra-deps {babashka/fs {:mvn/version "0.5.27"} + :extra-deps {babashka/fs {:mvn/version "0.5.30"} ring/ring-jetty-adapter {:mvn/version "1.10.0"} ;; stick with version that works on jdk8 - ch.qos.logback/logback-classic {:mvn/version "1.3.15" + ch.qos.logback/logback-classic {:mvn/version "1.3.16" :exclusions [org.slf4j/slf4j-api]} org.slf4j/jcl-over-slf4j {:mvn/version "2.0.17"} org.slf4j/jul-to-slf4j {:mvn/version "2.0.17"} @@ -29,10 +29,12 @@ :test {:extra-paths ["test"] :extra-deps {io.github.cognitect-labs/test-runner - {:git/tag "v0.5.1" :git/sha "dfb30dd"}} + {:git/tag "v0.5.1" :git/sha "dfb30dd"} + cheshire/cheshire {:mvn/version "6.1.0"} + nubank/matcher-combinators {:mvn/version "3.9.2"}} :main-opts ["-m" "cognitect.test-runner"]} ;; for consistent linting we use a specific version of clj-kondo through the jvm - :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2025.09.22"}} + :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version "2025.10.23"}} :override-deps {org.clojure/clojure {:mvn/version "1.12.3"}} :main-opts ["-m" "clj-kondo.main"]} :outdated {:extra-deps {com.github.liquidz/antq {:mvn/version "2.11.1276"} diff --git a/test/clj_http/lite/client_sanity_test.clj b/test/clj_http/lite/client_sanity_test.clj index 417bcdaa..4499e6c5 100644 --- a/test/clj_http/lite/client_sanity_test.clj +++ b/test/clj_http/lite/client_sanity_test.clj @@ -1,32 +1,53 @@ (ns clj-http.lite.client-sanity-test - "A small subset of tests suitable for sanity testing. - Used by babashka libs tests." + "A small subset of tests suitable for sanity testing." (:require [clj-http.lite.client :as client] + [cheshire.core :as json] + [matcher-combinators.test] + [matcher-combinators.matchers :as m] [clojure.test :as t :refer [deftest is]])) (deftest client-test (is (= 200 (:status (client/get "https://www.clojure.org" {:throw-exceptions false})))) - (is (= 200 (:status (client/get "https://postman-echo.com/get?foo1=bar1&foo2=bar2" {:throw-exceptions false})))) + (is (match? {:status 200 + :body (m/via json/decode {"method" "GET" + "args" {"foo1" ["bar1"] + "foo2" ["bar2"]}})} + (client/get "https://httpbingo.org/get?foo1=bar1&foo2=bar2" {:throw-exceptions false}))) - (is (= 200 (:status (client/post "https://postman-echo.com/post" {:throw-exceptions false})))) + (is (match? {:status 200 + :body (m/via json/decode {"method" "POST" + "headers" {"Content-Type" m/absent} + "args" {} + "data" ""})} + (client/post "https://httpbingo.org/post" {:throw-exceptions false}))) - (is (= 200 (:status (client/post "https://postman-echo.com/post" - {:body "{\"a\": 1}" - :headers {"X-Hasura-Role" "admin"} - :content-type :json - :accept :json - :throw-exceptions false})))) + (is (match? {:status 200 + :body (m/via json/decode {"method" "POST" + "headers" {"Content-Type" ["application/json; charset=UTF-8"] + "X-Hasura-Role" ["admin"]} + "data" "{\"a\": 1}"})} + (client/post "https://httpbingo.org/post" + {:body "{\"a\": 1}" + :headers {"X-Hasura-Role" "admin"} + :content-type :json + :accept :json + :throw-exceptions false}))) - (is (= 200 (:status (client/put "https://postman-echo.com/put" - {:body "{\"a\": 1}" - :headers {"X-Hasura-Role" "admin"} - :content-type :json - :accept :json - :throw-exceptions false}))))) + (is (match? {:status 200 + :body (m/via json/decode {"method" "PUT" + "headers" {"Content-Type" ["application/json; charset=UTF-8"] + "X-Hasura-Role" ["admin"]} + "data" "{\"a\": 1}"})} + (client/put "https://httpbingo.org/put" + {:body "{\"a\": 1}" + :headers {"X-Hasura-Role" "admin"} + :content-type :json + :accept :json + :throw-exceptions false})))) (deftest exception-test - (try (client/get "https://httpbin.org/status/404") + (try (client/get "https://httpbingo.org/status/404") (is false "should not reach here") (catch Exception e (is (:headers (ex-data e)))))) @@ -37,3 +58,4 @@ (is (= 200 (:status (client/get "https://expired.badssl.com" {:insecure? true})))) (is (thrown? Exception (client/get "https://expired.badssl.com")))) +