From 881c1d0d1863f947f10b19a18670ef42134c7b79 Mon Sep 17 00:00:00 2001 From: Kauwai Lucchesi Date: Fri, 13 Sep 2024 16:47:53 -0300 Subject: [PATCH 1/3] Add ctx based on fn arity --- test/spread/project.clj | 2 +- test/spread/src/house/jux__/test/spread__.clj | 53 ++++++++++++------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/test/spread/project.clj b/test/spread/project.clj index 4702332..ccd05b2 100644 --- a/test/spread/project.clj +++ b/test/spread/project.clj @@ -1,4 +1,4 @@ -(defproject house.jux/test.spread "2024.09.12" +(defproject house.jux/test.spread "2024.09.13-SNAPSHOT" :description "Support for highly expressive, two-dimensional tests represented as spreadsheets." :url "https://github.com/klauswuestefeld/simple-clj/tree/master/test/spread" diff --git a/test/spread/src/house/jux__/test/spread__.clj b/test/spread/src/house/jux__/test/spread__.clj index a8e4fa0..bb19ce1 100644 --- a/test/spread/src/house/jux__/test/spread__.clj +++ b/test/spread/src/house/jux__/test/spread__.clj @@ -90,7 +90,7 @@ (defn- ->initial-step [step] (-> step (assoc-in [:command :user] "nil") - (assoc-in [:command :function] "(fn [state & _ignored] state)") + (assoc-in [:command :function] "identity") (assoc-in [:command :result] "*"))) (defn- steps [structure] @@ -229,29 +229,45 @@ (catch Throwable t (throw (RuntimeException. (str "Error reading user: " (exception->message t))))))) +(defn- arity [function] + (-> function meta :arglists first count)) + +(defn- run-fn [fn-var args ctx] + (let [arity (arity fn-var) + args (if (= 3 arity) + (cond-> args + (= 1 (count args)) (conj ::ignored ctx) + (= 2 (count args)) (conj ctx)) + args)] + (apply fn-var args))) + +(defn- run-query [ctx segment] + (let [form (-> (str "(" segment ")") + compile-string + with-underline) ; The undeline symbol in the form refers to the var created with 'intern' above. + f (first form) + fn-var (if (keyword? f) f (resolve f)) + args (eval (vec (rest form)))] + (run-fn fn-var args ctx))) + (def initial-query-line 3) (defn execute-query-segments - ([state segments] - (execute-query-segments state segments initial-query-line)) + ([state ctx segments] + (execute-query-segments state ctx segments initial-query-line)) - ([value [segment & next-segments] query-line] + ([value ctx [segment & next-segments] query-line] (if (string/blank? segment) value (try (intern *ns* '_ value) ; Intern is a "def" that works at runtime (def creates the var at compile time). This indirection with this var is required because complex non-clojure objects such as #datascript/DB {...}, when added directy in the form, will give the error: "Can't embed object in code". Also it looks better in the print of the form than a huge state map. - (let [result (-> (str "(" segment ")") - compile-string - with-underline ; The undeline symbol in the form refers to the var created with 'intern' above. - eval)] - (execute-query-segments result next-segments (inc query-line))) + (let [result (run-query ctx segment)] + (execute-query-segments result ctx next-segments (inc query-line))) (catch Exception e {::wrapped-exception e :query-line query-line}))))) (defn- safe-query-result [state user segments] - (binding [*user* (eval-user user) - *timestamp* 1000000] - (execute-query-segments state segments))) + (execute-query-segments state {:user (eval-user user) :timestamp 1000000} segments)) (defn- execute-query [state query-results-line query-column-number [user & segments] expected-result] (let [column (query-column-idx->column query-column-number) @@ -271,21 +287,18 @@ (defn- resolve-command-fn [function-str line] (try - (eval-string function-str) + (->> function-str read-string resolve) (catch Exception e (throw-info! (str "Unable to resolve command '" function-str "' " (exception->message e)) {:line line, :column "B"})))) (defn- execute-command [state {:keys [function user params result result-coords]}] (binding [*result* (reset-result)] - (let [command (resolve-command-fn function (:line result-coords)) - command (if (string/blank? params) - #(command state) - #(command state (eval-string params))) + (let [command (resolve-command-fn function (:line result-coords)) + ctx {:user (eval-user user) :timestamp 1000000} + args (if (string/blank? params) [state] [state (eval-string params)]) new-state (try - (binding [*user* (eval-user user) - *timestamp* 1000000] - (command)) + (run-fn command args ctx) (catch Throwable e (set-result {::wrapped-exception e}) state))] From 15c8202133b6896a4d92edb5d2788f7a098b897b Mon Sep 17 00:00:00 2001 From: Kauwai Lucchesi Date: Fri, 13 Sep 2024 17:45:25 -0300 Subject: [PATCH 2/3] Update unit tests + remove unused deps --- test/spread/project.clj | 2 -- test/spread/src/house/jux__/test/spread__.clj | 2 -- test/spread/test/fixture/biz.clj | 11 +++++------ test/spread/test/unit/spread_test.clj | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/test/spread/project.clj b/test/spread/project.clj index ccd05b2..66847e8 100644 --- a/test/spread/project.clj +++ b/test/spread/project.clj @@ -10,8 +10,6 @@ [ring/ring-core "1.6.2"] [ring/ring-jetty-adapter "1.6.2"] [house.jux/biz.command-result "2024.09.05"] - [house.jux/biz.timestamp "2024.09.05"] - [house.jux/biz.user "2024.06.10"] [house.jux/exceptions "2024.06.10"] [house.jux/http.api "2024.06.11"] [house.jux/http.exceptions "2024.06.24"] diff --git a/test/spread/src/house/jux__/test/spread__.clj b/test/spread/src/house/jux__/test/spread__.clj index bb19ce1..0493c5b 100644 --- a/test/spread/src/house/jux__/test/spread__.clj +++ b/test/spread/src/house/jux__/test/spread__.clj @@ -4,9 +4,7 @@ clojure.stacktrace [clojure.string :as string] clojure.walk - [house.jux--.biz.user-- :refer [*user*]] [house.jux--.biz.command-result-- :refer [*result* get-result set-result reset-result]] - [house.jux--.biz.timestamp-- :refer [*timestamp*]] [simple.check2 :refer [check]])) (def previous-query-results (atom nil)) ;; TODO: remove this atom diff --git a/test/spread/test/fixture/biz.clj b/test/spread/test/fixture/biz.clj index 9fb46b5..966a883 100644 --- a/test/spread/test/fixture/biz.clj +++ b/test/spread/test/fixture/biz.clj @@ -1,10 +1,9 @@ (ns fixture.biz - (:require [house.jux--.biz.user-- :refer [user]] - [house.jux--.biz.command-result-- :refer [set-result]])) + (:require [house.jux--.biz.command-result-- :refer [set-result]])) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defn create-new-profile [state profile] - (let [state (->> (assoc profile :created-by (user)) +(defn create-new-profile [state profile {:keys [user]}] + (let [state (->> (assoc profile :created-by user) (assoc state :profile))] (set-result "Profile Created") state)) @@ -14,12 +13,12 @@ (:profile state)) #_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]} -(defn update-profile [state profile] +(defn update-profile [state profile {:keys [user]}] (when (-> profile :name (= "BOOM")) (throw (RuntimeException. "Invalid name"))) (let [state (-> state (update :profile merge profile) - (assoc-in [:profile :last-updated-by] (user)))] + (assoc-in [:profile :last-updated-by] user))] (set-result "Profile Updated") state)) diff --git a/test/spread/test/unit/spread_test.clj b/test/spread/test/unit/spread_test.clj index 17c7acf..9034f04 100644 --- a/test/spread/test/unit/spread_test.clj +++ b/test/spread/test/unit/spread_test.clj @@ -19,7 +19,7 @@ :steps [{:command {:user "nil", - :function "(fn [state & _ignored] state)", + :function "identity", :params "", :result "*", :result-coords {:line 7, :column "D"}}, From 7256f3cca2e8de5a60f02bd20b33e344c40feb2f Mon Sep 17 00:00:00 2001 From: Kauwai Lucchesi Date: Fri, 13 Sep 2024 17:49:35 -0300 Subject: [PATCH 3/3] Update spread version --- test/spread/project.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spread/project.clj b/test/spread/project.clj index 66847e8..fc40b6a 100644 --- a/test/spread/project.clj +++ b/test/spread/project.clj @@ -1,4 +1,4 @@ -(defproject house.jux/test.spread "2024.09.13-SNAPSHOT" +(defproject house.jux/test.spread "2024.09.13" :description "Support for highly expressive, two-dimensional tests represented as spreadsheets." :url "https://github.com/klauswuestefeld/simple-clj/tree/master/test/spread"