-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 08ec4f7
Showing
21 changed files
with
783 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{:lint-as {promesa.core/-> clojure.core/-> | ||
promesa.core/->> clojure.core/->> | ||
promesa.core/as-> clojure.core/as-> | ||
promesa.core/let clojure.core/let | ||
promesa.core/plet clojure.core/let | ||
promesa.core/loop clojure.core/loop | ||
promesa.core/recur clojure.core/recur | ||
promesa.core/with-redefs clojure.core/with-redefs | ||
promesa.core/doseq clojure.core/doseq}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{:lint-as | ||
{rewrite-clj.zip/subedit-> clojure.core/-> | ||
rewrite-clj.zip/subedit->> clojure.core/->> | ||
rewrite-clj.zip/edit-> clojure.core/-> | ||
rewrite-clj.zip/edit->> clojure.core/->>}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Run Tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- '*' | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Cache npm deps | ||
uses: actions/cache@v2 | ||
with: | ||
path: | | ||
node_modules | ||
~/.npm | ||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: ${{ runner.os }}-node | ||
|
||
- name: Install dependencies | ||
run: npm i | ||
|
||
- name: Run tests | ||
uses: coactions/setup-xvfb@v1 | ||
with: | ||
run: npm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Nodejs | ||
node_modules/ | ||
|
||
# Environment variables | ||
.env | ||
|
||
# OS generated files | ||
.DS_Store | ||
Thumbs.db | ||
|
||
# Clojure cache | ||
.cpcache/ | ||
|
||
# nREPL | ||
.joyride/.nrepl-port | ||
.nrepl-port | ||
|
||
# Calva | ||
.clj-kondo/.cache/ | ||
.lsp/.cache/ | ||
.lsp/sqlite*.db | ||
.calva/output-window/ | ||
|
||
# VS Code test-electron | ||
.vscode-test/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
;; clojure-lsp needs this config to analyze Joyride code | ||
;; To tell clojure-lsp about this file: | ||
;; 1. Add a source-alias to `.lsp/config.edn`. E.g.: | ||
;; :source-aliases #{:src :test :joyride} | ||
;; (The clojure-lsp defaults are `:src :test`.) | ||
;; 2. Add a `:joyride` alias to the project root deps.edn file. | ||
;; Minimal file content: | ||
;; {:aliases {:joyride {:extra-deps {joyride/workspace {:local/root ".joyride"}}}}} | ||
;; | ||
;; To also tell clojure-lsp about your Joyride user scripts, see instructions | ||
;; in your User Joyride config directory `deps.edn` file. | ||
;; (`~/.config/joyride/deps.edn` on Mac/Linux, somewhere similar on Windows?) | ||
{:deps {org.clojure/clojurescript {:mvn/version "1.11.54"} | ||
funcool/promesa {:mvn/version "9.0.471"} | ||
rewrite-clj/rewrite-clj {:mvn/version "1.1.46"}} | ||
:paths ["src" "scripts" "test"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
(ns workspace-activate | ||
(:require [joyride.core :as joyride] | ||
[seatbelt.runner] ;; The test runner needs to know when the workspace is activated | ||
)) | ||
|
||
;; This script only initializes the Backseat Driver app, | ||
;; It must be done before any keyboard shortcuts for the app works. | ||
;; See backseat-driver.app for a sample shortcut binding | ||
|
||
;; The app is intended to be a global (User) script. | ||
;; Try it out as a workspace script first, and if you want | ||
;; to use it in your projects,s see README.md for how to install | ||
;; it as a User script. | ||
|
||
(println "Backseat Driver: Hello World, from workspace_activate.cljs script") | ||
|
||
(defn- -main [] | ||
(println "Test Runner Example Workspace: -main called") | ||
(if js/process.env.JOYRIDE_HEADLESS | ||
(println "HEADLESS TEST RUN: Not Initializing Interactive things.") | ||
(do | ||
(println "Initializing interactive things...") | ||
; Beware of the Gilardi scenario: https://technomancy.us/143 | ||
(require '[my.thing]) | ||
((resolve 'my.thing/init!)))) | ||
(seatbelt.runner/ready-to-run-tests! "Workspace activated.")) | ||
|
||
(when (= (joyride/invoked-script) joyride/*file*) | ||
(-main)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
(ns my.thing | ||
(:require ["vscode" :as vscode])) | ||
|
||
(defn- button-label [n] | ||
(case n | ||
0 "Awesome!" | ||
1 "OK" | ||
2 "Roger that" | ||
"NYIP")) | ||
|
||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} | ||
(defn init! [] | ||
(vscode/window.showInformationMessage "My Thing is activated now." (button-label 0))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(ns my.util) | ||
|
||
(defn the-question [] | ||
:the-universe-and-everything) | ||
|
||
(defn the-answer [] | ||
42) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const cp = require("child_process"); | ||
const path = require("path"); | ||
const process = require("process"); | ||
const { | ||
downloadAndUnzipVSCode, | ||
resolveCliArgsFromVSCodeExecutablePath, | ||
runTests, | ||
} = require("@vscode/test-electron"); | ||
|
||
async function main(testWorkspace, isWatchMode) { | ||
console.log("launch-test-runner.js: testWorkspace", testWorkspace); | ||
try { | ||
const extensionTestsPath = path.resolve(__dirname, isWatchMode ? 'watchTests' : 'runTests'); | ||
const vscodeExecutablePath = await downloadAndUnzipVSCode('insiders'); | ||
const [cliPath, ...args] = | ||
resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath); | ||
|
||
const launchArgs = [ | ||
testWorkspace, | ||
...args, | ||
// '--verbose', | ||
'--disable-workspace-trust', | ||
'--install-extension', | ||
'betterthantomorrow.joyride', | ||
'--force', | ||
// Install other extensions that your Joyride scripts under test depend on. | ||
// E.g. Clojure project scripts often can have use for the Calva extension API. | ||
// '--install-extension', | ||
// 'betterthantomorrow.calva', | ||
// '--force', | ||
]; | ||
|
||
console.log("launch-test-runner.js: launchArgs", launchArgs); | ||
cp.spawnSync(cliPath, launchArgs, { | ||
encoding: "utf-8", | ||
stdio: "inherit", | ||
}); | ||
|
||
const runOptions = { | ||
vscodeExecutablePath, | ||
extensionTestsPath, | ||
launchArgs: [testWorkspace], | ||
}; | ||
await runTests(runOptions) | ||
.then((_result) => { | ||
console.info("launch-test-runner.js: 👍 Tests finished successfully"); | ||
}) | ||
.catch((err) => { | ||
console.error("launch-test-runner.js: 👎 Tests finished with failures or errors:", err); | ||
process.exit(1); | ||
}); | ||
} catch (err) { | ||
console.error("launch-test-runner.js: Failed to run tests:", err); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
const workspace = path.resolve(__dirname, "../../.."); | ||
console.info(`launch-test-runner.js: Using Workspace: ${workspace}`); | ||
|
||
const args = process.argv.slice(2); | ||
const isWatchMode = args.length > 0 && args[0] === "--watch"; | ||
|
||
main(workspace, isWatchMode); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const vscode = require('vscode'); | ||
|
||
exports.run = async () => { | ||
console.log("runTests.js: run started"); | ||
// Execute and await any VS Code commands that should be run before the tests start. | ||
// (E.g. activating an extension, opening a file, etc.) | ||
// await vscode.commands.executeCommand('some.command'); | ||
return vscode.commands.executeCommand( | ||
'joyride.runCode', | ||
`(require '[seatbelt.runner :as runner]) | ||
(runner/run-tests!+ "Waiting for workspace to activate...")` | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
(ns seatbelt.runner | ||
(:require ["vscode" :as vscode] | ||
["path" :as path] | ||
[clojure.string :as string] | ||
[cljs.test] | ||
[promesa.core :as p])) | ||
|
||
(def ^:private default-db {:runner+ nil | ||
:ready-to-run? false | ||
:pass 0 | ||
:fail 0 | ||
:error 0}) | ||
|
||
(def ^:private !state (atom default-db)) | ||
|
||
(defn ^:private init-counters! [] | ||
(swap! !state merge (select-keys default-db [:pass :fail :error]))) | ||
|
||
(defn- write [& xs] | ||
(js/process.stdout.write (string/join " " xs))) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :begin-test-var] [m] | ||
(write "===" (str (-> m :var meta :name) ": "))) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :end-test-var] [_m] | ||
(write " ===\n")) | ||
|
||
(def original-pass (get-method cljs.test/report [:cljs.test/default :pass])) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :pass] [m] | ||
(binding [*print-fn* write] (original-pass m)) | ||
(write "✅") | ||
(swap! !state update :pass inc)) | ||
|
||
(def original-fail (get-method cljs.test/report [:cljs.test/default :fail])) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :fail] [m] | ||
(binding [*print-fn* write] (original-fail m)) | ||
(write "❌") | ||
(swap! !state update :fail inc)) | ||
|
||
(def original-error (get-method cljs.test/report [:cljs.test/default :error])) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :error] [m] | ||
(binding [*print-fn* write] (original-error m)) | ||
(write "🚫") | ||
(swap! !state update :error inc)) | ||
|
||
(def original-end-run-tests (get-method cljs.test/report [:cljs.test/default :end-run-tests])) | ||
|
||
(defmethod cljs.test/report [:cljs.test/default :end-run-tests] [m] | ||
(binding [*print-fn* write] | ||
(original-end-run-tests m) | ||
(let [{:keys [runner+ pass fail error] :as state} @!state | ||
passed-minimum-threshold 2 | ||
fail-reason (cond | ||
(< 0 (+ fail error)) "seatbelt: 👎 FAILURE: Some tests failed or errored" | ||
(< pass passed-minimum-threshold) (str "seatbelt: 👎 FAILURE: Less than " passed-minimum-threshold " assertions passed. (Passing: " pass ")") | ||
:else nil)] | ||
(println "seatbelt: tests run, results:" | ||
(select-keys state [:pass :fail :error]) "\n") | ||
(when runner+ ; When not using the runner, there's no promise to resolve or reject | ||
(if fail-reason | ||
(p/reject! runner+ fail-reason) | ||
(p/resolve! runner+ true)))))) | ||
|
||
(defn- run-tests-impl!+ [test-nss] | ||
(println "seatbelt: Starting tests...") | ||
(init-counters!) | ||
(try | ||
(doseq [test-ns test-nss] | ||
(require test-ns :reload)) | ||
(apply cljs.test/run-tests test-nss) | ||
(catch :default e | ||
(p/reject! (:runner+ @!state) e)))) | ||
|
||
(defn ready-to-run-tests! | ||
"The test runner will wait for this to be called before running any tests. | ||
`ready-message` will be logged when this is called" | ||
[ready-message] | ||
(println "seatbelt:" ready-message) | ||
(swap! !state assoc :ready-to-run? true)) | ||
|
||
(defn run-ns-tests!+ | ||
"Runs the `test-nss` test | ||
NB: Will wait for `ready-to-run-tests!` to be called before doing so. | ||
`waiting-message` will be logged if the test runner is waiting." | ||
[test-nss waiting-message] | ||
(let [runner+ (p/deferred)] | ||
(swap! !state assoc :runner+ runner+) | ||
(if (:ready-to-run? @!state) | ||
(run-tests-impl!+ test-nss) | ||
(do | ||
(println "seatbelt: " waiting-message) | ||
(add-watch !state :runner (fn [k r _o n] | ||
(when (:ready-to-run? n) | ||
(remove-watch r k) | ||
(run-tests-impl!+ test-nss)))))) | ||
runner+)) | ||
|
||
(defn- uri->ns-symbol [uri] | ||
(-> uri | ||
(vscode/workspace.asRelativePath) | ||
(string/split path/sep) | ||
(->> (drop 2) | ||
(string/join ".")) | ||
(string/replace "_" "-") | ||
(string/replace #"\.clj[cs]$" "") | ||
symbol)) | ||
|
||
(defn- glob->ns-symbols [glob] | ||
(p/let [uris (vscode/workspace.findFiles glob)] | ||
(map uri->ns-symbol uris))) | ||
|
||
(defn run-tests!+ | ||
"Runs the tests in any `_test.cljs` files in `.joyride/src/test/` | ||
NB: Will wait for `ready-to-run-tests!` to be called before doing so. | ||
`waiting-message` will be logged if the test runner is waiting." | ||
[waiting-message] | ||
(p/let [nss (glob->ns-symbols ".joyride/src/test/**/*_test.clj[sc]")] | ||
(println "seatbelt: Running tests in these" (count nss) "namespaces" (pr-str nss)) | ||
(run-ns-tests!+ nss waiting-message))) | ||
|
||
(defn watcher-test-run!+ | ||
([uri reason] | ||
(watcher-test-run!+ uri reason nil)) | ||
([uri reason waiting-message] | ||
(println reason (vscode/workspace.asRelativePath uri)) | ||
(println "Running tests...") | ||
(when-not (= "." uri) | ||
(require (uri->ns-symbol uri) :reload-all)) | ||
(-> (run-tests!+ waiting-message) | ||
(p/then (fn [_] | ||
(js/setImmediate | ||
#(println "🟢 YAY! 🟢")))) | ||
(p/catch (fn [e] | ||
; No sound? Check your settings for terminal.integrated.enableBell | ||
(js/setImmediate #(do (println "\u0007") | ||
(println "🔴 NAY! 🔴" e))))) | ||
(p/finally (fn [] | ||
(js/setImmediate | ||
#(println "Waiting for changes..."))))))) | ||
|
||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} | ||
(defn watch!+ [waiting-message] | ||
(let [glob-pattern "**/.joyride/**/*.cljs" | ||
watcher (vscode/workspace.createFileSystemWatcher glob-pattern)] | ||
(.onDidChange watcher (fn [uri] | ||
(watcher-test-run!+ uri "File changed:"))) | ||
(.onDidCreate watcher (fn [uri] | ||
(watcher-test-run!+ uri "File created:"))) | ||
(.onDidDelete watcher (fn [uri] | ||
(watcher-test-run!+ uri "File deleted:"))) | ||
(watcher-test-run!+ "." "Watcher started" waiting-message)) | ||
; We leave the vscode electron test runner waiting for this promise | ||
(p/deferred)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const vscode = require('vscode'); | ||
|
||
exports.run = async () => { | ||
console.log("runTests.js: run started"); | ||
// Execute and await any VS Code commands that should be run before the tests start. | ||
// (E.g. activating an extension, opening a file, etc.) | ||
// await vscode.commands.executeCommand('some.command'); | ||
return vscode.commands.executeCommand( | ||
'joyride.runCode', | ||
`(require '[seatbelt.runner :as runner]) | ||
(runner/watch!+ "Waiting for workspace to activate...")` | ||
); | ||
}; |
Oops, something went wrong.