init commit

This commit is contained in:
2026-01-18 22:07:48 -05:00
parent 9c019e3d41
commit 56dde9cf91
43 changed files with 2925 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
(ns spiceflow.adapters-test
(:require [clojure.test :refer [deftest testing is]]
[spiceflow.adapters.protocol :as proto]
[spiceflow.adapters.claude :as claude]
[spiceflow.adapters.opencode :as opencode]))
(deftest test-claude-adapter
(testing "Provider name"
(let [adapter (claude/create-adapter)]
(is (= :claude (proto/provider-name adapter)))))
(testing "Parse JSONL messages"
(let [adapter (claude/create-adapter)]
;; User message
(let [parsed (proto/parse-output adapter
"{\"type\":\"user\",\"message\":{\"content\":\"Hello\"},\"timestamp\":\"2024-01-01T00:00:00Z\"}")]
(is (= :user (:role parsed)))
(is (= "Hello" (:content parsed))))
;; Assistant message
(let [parsed (proto/parse-output adapter
"{\"type\":\"assistant\",\"message\":{\"content\":\"Hi!\"},\"timestamp\":\"2024-01-01T00:00:00Z\"}")]
(is (= :assistant (:role parsed)))
(is (= "Hi!" (:content parsed))))
;; Content delta (streaming)
(let [parsed (proto/parse-output adapter
"{\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"text\":\"Hello\"}}")]
(is (= :content-delta (:event parsed)))
(is (= "Hello" (:text parsed))))
;; Message stop
(let [parsed (proto/parse-output adapter
"{\"type\":\"message_stop\"}")]
(is (= :message-stop (:event parsed))))
;; Empty line
(is (nil? (proto/parse-output adapter "")))
(is (nil? (proto/parse-output adapter " "))))))
(deftest test-opencode-adapter
(testing "Provider name"
(let [adapter (opencode/create-adapter)]
(is (= :opencode (proto/provider-name adapter)))))
(testing "Parse stream output"
(let [adapter (opencode/create-adapter)]
;; JSON content
(let [parsed (proto/parse-output adapter "{\"content\":\"Hello\"}")]
(is (= :content-delta (:event parsed)))
(is (= "Hello" (:text parsed))))
;; Plain text
(let [parsed (proto/parse-output adapter "Some output text")]
(is (= :content-delta (:event parsed)))
(is (= "Some output text" (:text parsed))))
;; Done message
(let [parsed (proto/parse-output adapter "{\"done\":true}")]
(is (= :message-stop (:event parsed)))))))
(deftest test-discover-sessions
(testing "Claude adapter discovers sessions (may be empty)"
(let [adapter (claude/create-adapter)
sessions (proto/discover-sessions adapter)]
(is (vector? sessions))
(doseq [session sessions]
(is (:external-id session))
(is (= :claude (:provider session))))))
(testing "OpenCode adapter discovers sessions (may fail if not installed)"
(let [adapter (opencode/create-adapter)]
;; This may fail if opencode is not installed, so we just check
;; that it doesn't throw an unexpected exception
(try
(let [sessions (proto/discover-sessions adapter)]
(is (or (nil? sessions) (vector? sessions))))
(catch Exception _
;; OK if opencode is not installed
(is true))))))
+86
View File
@@ -0,0 +1,86 @@
(ns spiceflow.db-test
(:require [clojure.test :refer [deftest testing is use-fixtures]]
[spiceflow.db.protocol :as db]
[spiceflow.db.memory :as memory]
[spiceflow.db.sqlite :as sqlite]))
;; Test both implementations
(def ^:dynamic *store* nil)
(defn memory-fixture [f]
(binding [*store* (memory/create-store)]
(f)))
(defn sqlite-fixture [f]
(let [db-path (str "/tmp/spiceflow-test-" (System/currentTimeMillis) ".db")]
(binding [*store* (sqlite/create-store db-path)]
(try
(f)
(finally
(clojure.java.io/delete-file db-path true))))))
;; Session tests
(deftest test-session-crud
(testing "Create and retrieve session"
(let [session (db/save-session *store* {:provider :claude
:external-id "test-123"
:title "Test Session"
:working-dir "/home/test"})]
(is (:id session))
(is (= :claude (:provider session)))
(is (= "test-123" (:external-id session)))
(is (:created-at session))
;; Get session
(let [retrieved (db/get-session *store* (:id session))]
(is (= (:id session) (:id retrieved)))
(is (= "Test Session" (:title retrieved))))))
(testing "List sessions"
(let [sessions (db/get-sessions *store*)]
(is (>= (count sessions) 1))))
(testing "Update session"
(let [session (first (db/get-sessions *store*))
updated (db/update-session *store* (:id session) {:title "Updated Title"
:status :running})]
(is (= "Updated Title" (:title updated)))
(is (= :running (:status updated)))))
(testing "Delete session"
(let [session (first (db/get-sessions *store*))]
(db/delete-session *store* (:id session))
(is (nil? (db/get-session *store* (:id session)))))))
;; Message tests
(deftest test-message-crud
(testing "Create and retrieve messages"
(let [session (db/save-session *store* {:provider :claude
:external-id "msg-test"
:title "Message Test"})
msg1 (db/save-message *store* {:session-id (:id session)
:role :user
:content "Hello"})
msg2 (db/save-message *store* {:session-id (:id session)
:role :assistant
:content "Hi there!"
:metadata {:model "claude-3"}})]
(is (:id msg1))
(is (:id msg2))
;; Get messages
(let [messages (db/get-messages *store* (:id session))]
(is (= 2 (count messages)))
(is (= :user (:role (first messages))))
(is (= :assistant (:role (second messages))))
(is (= {:model "claude-3"} (:metadata (second messages)))))
;; Get single message
(let [retrieved (db/get-message *store* (:id msg1))]
(is (= "Hello" (:content retrieved)))))))
;; Run with memory store
(use-fixtures :each memory-fixture)
;; Uncomment to run with SQLite
;; (use-fixtures :each sqlite-fixture)