diff --git a/.github/workflows/clojure.yml b/.github/workflows/clojure.yml index 096a9bc..5aba616 100644 --- a/.github/workflows/clojure.yml +++ b/.github/workflows/clojure.yml @@ -3,17 +3,39 @@ name: Clojure CI on: push: branches: [ master ] + tags: [ '[0-9]*' ] pull_request: branches: [ master ] jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - uses: DeLaGuardo/setup-clojure@13 + with: + cli: latest + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gitlibs + .cpcache + key: ${{ runner.os }}-deps-${{ hashFiles('deps.edn') }} + restore-keys: ${{ runner.os }}-deps- - name: Install dependencies - run: lein deps + run: clojure -P -M:test - name: Run tests - run: lein test - - name: Coverage - run: lein coverage + run: clojure -M:test -m cognitect.test-runner + - name: Deploy to Clojars + if: startsWith(github.ref, 'refs/tags/') + env: + CLOJARS_USERNAME: ${{ secrets.CLOJARS_USERNAME }} + CLOJARS_PASSWORD: ${{ secrets.CLOJARS_PASSWORD }} + RELEASE_VERSION: ${{ github.ref_name }} + run: clojure -T:build deploy-jar diff --git a/.github/workflows/clojurescript.yml b/.github/workflows/clojurescript.yml index 6df2be2..b2f3480 100644 --- a/.github/workflows/clojurescript.yml +++ b/.github/workflows/clojurescript.yml @@ -8,15 +8,15 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '21' - uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '22' - run: npm install - run: npm test diff --git a/.gitignore b/.gitignore index 8ed779b..32a69ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,9 @@ /target /classes -/checkouts -pom.xml -pom.xml.asc *.jar *.class -/.lein-* +pom.xml /.nrepl-port -.hgignore -.hg/ -resources/public/cljs -/out -figwheel_server.log -/.cljs_rhino_repl +.cpcache .shadow-cljs node_modules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..541ed15 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,14 @@ +# Contributing + +Pull requests are welcome. Please run the test suite and check that all tests pass prior to submission. + +``` +make test # Clojure tests +make test-cljs # ClojureScript tests (requires npm install) +``` + +## Releasing + +1. Commit and push any final changes to master +2. Tag the release: `git tag && git push --tags` — CI deploys to Clojars +3. Verify the release appears on https://clojars.org/tortue/spy diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ea7fa6c --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +.PHONY: test test-cljs clean jar deploy + +test: + clojure -M:test -m cognitect.test-runner + +test-cljs: + npm test + +clean: + clojure -T:build clean + +jar: + clojure -T:build jar + +deploy: + clojure -T:build deploy-jar diff --git a/README.md b/README.md index b5b36b4..0174465 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,23 @@ Spy - a Clojure and ClojureScript library for stubs, spies and mocks. This library is aimed at users of [clojure.test](https://clojure.github.io/clojure/clojure.test-api.html). -It records calls and responses to and from a function, allowing you to verify interactions. Terms used in this library are as follows, there are many different names for Mocks, see [Test Doubles, Fakes, Mocks and Stubs](https://blog.pragmatists.com/test-doubles-fakes-mocks-and-stubs-1a7491dfa3da) for more detail. +It records calls and responses to and from a function, allowing you to verify interactions. 1. Stub - function that returns a hardcoded value 2. Spy - wrapper around a function allowing verification of interactions with the function -3. Mock - function with a fake implementation to be used in place of the real thing +3. Mock - function with a fake implementation to be used in place of the real thing + +## Installation + +**deps.edn** +```clojure +{:deps {tortue/spy {:mvn/version "2.15.0"}}} +``` + +**Leiningen (project.clj)** +```clojure +[tortue/spy "2.15.0"] +``` ## Usage @@ -262,23 +274,13 @@ can also be used to spy on multiple protocols: `(spy.protocol/spy Proto1...Proto ## Contributing -Pull requests are welcome. Please run the test suite and check that all tests pass prior to submission. - -Tests: -``` -$ lein test -``` - -Code coverage: -``` -$ lein cloverage -``` +Pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for details. ## License ``` MIT License -Copyright (c) 2025 Alexander James King +Copyright (c) 2026 Alexander James King Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/bin/setup b/bin/setup index 465a23b..e0b9c32 100755 --- a/bin/setup +++ b/bin/setup @@ -4,5 +4,5 @@ set -euxo pipefail cd "$(dirname "${BASH_SOURCE[0]}")/.." -lein deps +clj -P -M:test npm install diff --git a/bin/test b/bin/test index c58d465..d85e3fe 100755 --- a/bin/test +++ b/bin/test @@ -4,5 +4,5 @@ set -euxo pipefail cd "$(dirname "${BASH_SOURCE[0]}")/.." -lein test +clj -M:test -m cognitect.test-runner npm test diff --git a/build.clj b/build.clj new file mode 100644 index 0000000..f64b6a1 --- /dev/null +++ b/build.clj @@ -0,0 +1,42 @@ +(ns build + (:require [clojure.tools.build.api :as b] + [deps-deploy.deps-deploy :as deploy])) + +(def lib 'tortue/spy) +(def version (or (System/getenv "RELEASE_VERSION") "dev")) +(def class-dir "target/classes") +(def src-dirs ["src/clj" "src/cljc" "src/cljs" "resources"]) +(def basis (delay (b/create-basis {:project "deps.edn"}))) +(def jar-file (format "target/%s-%s.jar" (name lib) version)) + +(defn- assert-release-version [] + (assert (re-matches #"\d+\.\d+\.\d+" version) + (str "RELEASE_VERSION must be set to a valid version (e.g. 2.16.0), got: " version))) + +(defn clean [_] + (b/delete {:path "target"})) + +(defn jar [_] + (b/delete {:path class-dir}) + (b/write-pom {:class-dir class-dir + :lib lib + :version version + :basis @basis + :description "Spy - a Clojure and ClojureScript library for stubs, spies and mocks" + :url "https://github.com/alexanderjamesking/spy" + :scm {:url "https://github.com/alexanderjamesking/spy"} + :pom-data [[:licenses + [:license + [:name "MIT License"] + [:url "https://opensource.org/licenses/MIT"]]]]}) + (b/copy-dir {:src-dirs src-dirs + :target-dir class-dir}) + (b/jar {:class-dir class-dir + :jar-file jar-file})) + +(defn deploy-jar [_] + (assert-release-version) + (jar nil) + (deploy/deploy {:installer :remote + :artifact jar-file + :pom-file (b/pom-path {:lib lib :class-dir class-dir})})) diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000..a163a3e --- /dev/null +++ b/deps.edn @@ -0,0 +1,11 @@ +{:paths ["src/clj" "src/cljc" "src/cljs" "resources"] + :deps {} + :aliases + {:provided {:extra-deps {org.clojure/clojure {:mvn/version "1.12.1"} + org.clojure/clojurescript {:mvn/version "1.12.42"}}} + :test {:extra-paths ["test/clj" "test/cljc"] + :extra-deps {org.clojure/clojure {:mvn/version "1.12.1"} + io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}}} + :build {:deps {io.github.clojure/tools.build {:mvn/version "0.10.5"} + slipset/deps-deploy {:mvn/version "0.2.2"}} + :ns-default build}}} diff --git a/package-lock.json b/package-lock.json index 67d37c2..9c14d8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "shadow-cljs": "3.1.7" + "shadow-cljs": "3.3.5" } }, "node_modules/base64-js": { @@ -99,9 +99,10 @@ } }, "node_modules/shadow-cljs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-3.1.7.tgz", - "integrity": "sha512-q1SCy5m5EpNfrn6C0vKa2ho6gwW6rdSU1Ge22HbbZ813TpR/1hBXdlgTF2RE49yIqJxxhVtfcLz0jWa0Ul32IQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-3.3.5.tgz", + "integrity": "sha512-MzkpTVJQYuUreIMFsQRXHcoMA6FaqzyLkWauAvdYHq3TtY/HCWY5szmtd9KkvZdHMy/q7sUWmebKiFvRtE1Alg==", + "license": "ISC", "dependencies": { "buffer": "^6.0.3", "process": "^0.11.10", @@ -216,9 +217,9 @@ "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" }, "shadow-cljs": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-3.1.7.tgz", - "integrity": "sha512-q1SCy5m5EpNfrn6C0vKa2ho6gwW6rdSU1Ge22HbbZ813TpR/1hBXdlgTF2RE49yIqJxxhVtfcLz0jWa0Ul32IQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-3.3.5.tgz", + "integrity": "sha512-MzkpTVJQYuUreIMFsQRXHcoMA6FaqzyLkWauAvdYHq3TtY/HCWY5szmtd9KkvZdHMy/q7sUWmebKiFvRtE1Alg==", "requires": { "buffer": "^6.0.3", "process": "^0.11.10", diff --git a/package.json b/package.json index eda50ee..cbc4744 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "dependencies": { - "shadow-cljs": "3.1.7" + "shadow-cljs": "3.3.5" }, "scripts": { "test": "shadow-cljs compile test && node target/test.js" diff --git a/project.clj b/project.clj deleted file mode 100644 index 0795f68..0000000 --- a/project.clj +++ /dev/null @@ -1,14 +0,0 @@ -(defproject tortue/spy "2.16.0-SNAPSHOT" - :description "Spy - a Clojure and ClojureScript library for stubs, spies and mocks" - :url "https://github.com/alexanderjamesking/spy" - :license {:name "MIT License" - :url "https://opensource.org/licenses/MIT" - :year 2022 - :key "mit"} - :plugins [[lein-cloverage "1.2.4"]] - :profiles {:provided {:dependencies [[org.clojure/clojure "1.12.1"] - [org.clojure/clojurescript "1.12.42"]]}} - :source-paths ["src/clj" "src/cljc" "src/cljs"] - :test-paths ["test/clj" "test/cljc"] - :deploy-repositories [["releases" :clojars]] - :aliases {"coverage" ["cloverage" "--ns-exclude-regex" "spy.test.cljs"]}) diff --git a/resources/clj-kondo.exports/tortue/spy/config.edn b/resources/clj-kondo.exports/tortue/spy/config.edn new file mode 100644 index 0000000..041e25e --- /dev/null +++ b/resources/clj-kondo.exports/tortue/spy/config.edn @@ -0,0 +1,11 @@ +{:lint-as {spy.assert/called? clojure.core/assert + spy.assert/not-called? clojure.core/assert + spy.assert/called-once? clojure.core/assert + spy.assert/called-n-times? clojure.core/assert + spy.assert/called-with? clojure.core/assert + spy.assert/not-called-with? clojure.core/assert + spy.assert/called-once-with? clojure.core/assert + spy.assert/called-at-least-once? clojure.core/assert + spy.assert/called-at-least-n-times? clojure.core/assert + spy.assert/called-no-more-than-once? clojure.core/assert + spy.assert/called-no-more-than-n-times? clojure.core/assert}}