|
11 | 11 | (defn- generate-events
|
12 | 12 | [data-coll]
|
13 | 13 | (let [events (map #(str "data: " (json/generate-string %)) data-coll)]
|
14 |
| - (str/join "\n\n" (concat events ["data: [DONE]"])))) |
| 14 | + (str/join |
| 15 | + (eduction |
| 16 | + cat |
| 17 | + (map #(str % "\n\n")) |
| 18 | + [events ["data: [DONE]"]])))) |
15 | 19 |
|
16 | 20 | (defn- stream-string
|
17 | 21 | [^PipedOutputStream output-stream ^String s]
|
18 | 22 | (future
|
19 | 23 | (doseq [c (seq (.getBytes s))]
|
20 | 24 | (.write output-stream ^int c)
|
21 | 25 | (.flush output-stream)
|
22 |
| - (Thread/sleep 1)))) |
| 26 | + (Thread/sleep 1)) |
| 27 | + (.close output-stream))) |
23 | 28 |
|
24 | 29 | (deftest sse-events-test
|
25 | 30 | (testing "channel can get events"
|
|
33 | 38 | (is (= (first test-data)
|
34 | 39 | (a/<!! events)))
|
35 | 40 | (is (= (second test-data)
|
| 41 | + (a/<!! events))) |
| 42 | + (is (= :done |
| 43 | + (a/<!! events))) |
| 44 | + (is (= nil |
| 45 | + (a/poll! events)))))))) |
| 46 | + |
| 47 | + (testing "channel events with `stream/close?` parameter" |
| 48 | + (let [test-data [{:text "hello"} {:text "world"}] |
| 49 | + test-events (generate-events test-data)] |
| 50 | + (with-open [output-stream (PipedOutputStream.) |
| 51 | + input-stream (PipedInputStream. output-stream)] |
| 52 | + (with-redefs [http/request (constantly {:body input-stream})] |
| 53 | + (let [events (sse/sse-events {:params {:stream/close? true}})] |
| 54 | + (stream-string output-stream test-events) |
| 55 | + (is (= (first test-data) |
| 56 | + (a/<!! events))) |
| 57 | + (is (= (second test-data) |
| 58 | + (a/<!! events))) |
| 59 | + (is (= :done |
| 60 | + (a/<!! events))) |
| 61 | + (is (= nil |
36 | 62 | (a/<!! events))))))))
|
37 | 63 |
|
| 64 | + (testing "channel events with `:on-next`" |
| 65 | + (doseq [close? [true false]] |
| 66 | + (let [test-data [{:text "hello"} {:text "world"}] |
| 67 | + test-events (generate-events test-data)] |
| 68 | + (with-open [output-stream (PipedOutputStream.) |
| 69 | + input-stream (PipedInputStream. output-stream)] |
| 70 | + (with-redefs [http/request (constantly {:body input-stream})] |
| 71 | + (let [events (sse/sse-events {:stream/close? close?}) |
| 72 | + results (promise) |
| 73 | + ;; accumulate results and fulfill promise when done |
| 74 | + on-next (let [acc (volatile! [])] |
| 75 | + (fn [x] |
| 76 | + (vswap! acc conj x) |
| 77 | + (when (= x (last test-data)) |
| 78 | + (deliver results @acc))))] |
| 79 | + (sse/deliver-events events {:on-next on-next}) |
| 80 | + (stream-string output-stream test-events) |
| 81 | + (is (= test-data |
| 82 | + @results)))))))) |
| 83 | + |
38 | 84 | (testing "support multibytes"
|
39 | 85 | (let [test-data [{:text "こんにちは"} {:text "你好"}]
|
40 | 86 | test-events (generate-events test-data)]
|
|
0 commit comments