Skip to content

Commit 98d3fb4

Browse files
committed
Port pprint tests: 12 tests, 78 assertions (content-equivalent)
Content-equivalent approach: test names from upstream test_pretty.clj, CW-adapted test content. Tests pprint output, print-length, print-level, reference types (atom/delay/agent), print-table, wrapping behavior, empty collections, strings, nested structures, special values.
1 parent f2c7782 commit 98d3fb4

2 files changed

Lines changed: 306 additions & 5 deletions

File tree

‎.dev/memo.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Session handover document. Read at session start.
88
- Coverage: 835+ vars (635/706 core, 16 namespaces total)
99
- Wasm engine: zwasm v0.7.0 (GitHub URL dependency, build.zig.zon)
1010
- Bridge: `src/wasm/types.zig` (751 lines, thin wrapper over zwasm)
11-
- 48 upstream test files, all passing. 6/6 e2e tests pass.
11+
- 49 upstream test files, all passing. 6/6 e2e tests pass.
1212
- Benchmarks: `bench/wasm_history.yaml` (zwasm-0.7.0 entry = latest baseline)
1313

1414
## Strategic Direction
@@ -28,21 +28,27 @@ Phase 53: Hardening & pprint Tests — IN PROGRESS
2828
- [x] 53.3: Align distinct? to upstream (enabled by 53.2)
2929
- [x] 53.4: Fix BigDecimal exponent notation (1.0e+1M)
3030
- [x] 53.5: Fix colon in symbol/keyword literals
31-
- [ ] 53.6: Port pprint tests (content-equivalent, CW-adapted)
31+
- [x] 53.6: Port pprint tests (content-equivalent, CW-adapted)
3232
- [ ] 53.7: Full regression + update docs
3333

3434
## Current Task
3535

36-
53.6: Port pprint tests (content-equivalent, CW-adapted)
36+
53.7: Full regression + update docs
3737

3838
## Previous Task
3939

40-
Phase 52: Quality & Alignment (complete)
41-
- See Phase 52 commit history for details
40+
53.6: Port pprint tests — 12 tests, 78 assertions
41+
- Content-equivalent approach: test names from upstream, CW-adapted content
42+
- Tests: pprint-test, pprint-reader-macro-test, print-length-tests,
43+
print-level-tests, pprint-datastructures-tests, pprint-wrapping-test,
44+
pprint-empty-collections-test, pprint-strings-test, pprint-nested-test,
45+
print-table-test, pprint-special-values-test, pprint-print-length-and-level-combined
46+
- Both VM + TreeWalk passing
4247

4348
## Known Issues
4449

4550
- apply on infinite lazy seq realizes eagerly (deferred — no tests need it)
51+
- pprint on infinite lazy seq hangs (realizeValue in singleLine/pprintImpl)
4652
- binding *ns* doesn't affect read-string for auto-resolved keywords
4753
- Regex capture groups/backreferences not supported
4854

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
9+
;; Author: Tom Faulhaber (upstream), adapted for CW
10+
11+
;; Upstream: clojure/test/clojure/test_clojure/pprint/test_pretty.clj
12+
;; Upstream lines: 415
13+
;; CLJW markers: 22
14+
;; CLJW: Content-equivalent tests. Upstream uses cl-format, simple-dispatch,
15+
;; code-dispatch, with-pprint-dispatch, write, pprint-logical-block etc.
16+
;; which CW does not implement. Test names borrowed from upstream but test
17+
;; content adapted to exercise CW's pprint builtin behavior.
18+
19+
(ns clojure.test-clojure.pprint
20+
;; CLJW: removed (:refer-clojure :exclude [format]), clojure.string,
21+
;; test-helper, test-clojure.pprint.test-helper, full clojure.pprint use.
22+
;; CW pprint is a Zig builtin; cl-format/dispatch not available.
23+
(:use clojure.test)
24+
(:require [clojure.pprint :refer [pprint print-table]]))
25+
26+
;; CLJW: upstream uses (simple-tests ...) macro throughout.
27+
;; CW uses standard (deftest ... (is ...)) since simple-tests is not available.
28+
29+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30+
;;; pprint-test — basic pretty-print output
31+
;;; CLJW: upstream tests cl-format with simple-dispatch and code-dispatch.
32+
;;; CW tests basic pprint output for scalar values and simple forms.
33+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34+
35+
(deftest pprint-test
36+
;; Scalar values
37+
(is (= "42\n" (with-out-str (pprint 42))))
38+
(is (= "nil\n" (with-out-str (pprint nil))))
39+
(is (= "true\n" (with-out-str (pprint true))))
40+
(is (= "false\n" (with-out-str (pprint false))))
41+
(is (= ":foo\n" (with-out-str (pprint :foo))))
42+
(is (= "\"hello\"\n" (with-out-str (pprint "hello"))))
43+
(is (= "foo\n" (with-out-str (pprint 'foo))))
44+
;; CLJW: upstream tests write with :stream nil and dispatch.
45+
;; CW tests pprint of quoted forms.
46+
(is (= "(defn foo [x y] (+ x y))\n"
47+
(with-out-str (pprint '(defn foo [x y] (+ x y))))))
48+
;; CLJW: upstream tests var printing with #'Foo.
49+
;; CW tests var printing.
50+
(is (= "#'clojure.core/+\n" (with-out-str (pprint #'clojure.core/+)))))
51+
52+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53+
;;; pprint-reader-macro-test — reader macro forms through pprint
54+
;;; CLJW: upstream tests with code-dispatch preserving #(), @@, '.
55+
;;; CW pprint does not have code-dispatch, so reader macro forms print
56+
;;; as expanded forms (quote → (quote ...), deref → (deref ...)).
57+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
58+
59+
(deftest pprint-reader-macro-test
60+
;; CLJW: CW expands reader macros, so 'foo becomes (quote foo)
61+
(is (= "(quote foo)\n" (with-out-str (pprint '(quote foo)))))
62+
;; CLJW: deref form
63+
(is (= "(deref x)\n" (with-out-str (pprint '(deref x)))))
64+
;; fn literal — read-string reads #(...) into (fn* [...] ...)
65+
;; CLJW: CW expands #(first %) to (fn* [%1] (first %1))
66+
(is (= "(fn* [%1] (first %1))\n"
67+
(with-out-str (pprint (read-string "#(first %)"))))))
68+
69+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
70+
;;; print-length-tests — *print-length* interaction with pprint
71+
;;; CLJW: upstream tests lists, vectors, sorted-sets, sorted-maps, int-arrays.
72+
;;; CW tests lists, vectors, sets, maps (no sorted-set/sorted-map/int-array).
73+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
74+
75+
(deftest print-length-tests
76+
;; Lists
77+
(is (= "(a ...)\n" (with-out-str (binding [*print-length* 1] (pprint '(a b c d e f))))))
78+
(is (= "(a b ...)\n" (with-out-str (binding [*print-length* 2] (pprint '(a b c d e f))))))
79+
(is (= "(a b c d e f)\n" (with-out-str (binding [*print-length* 6] (pprint '(a b c d e f))))))
80+
(is (= "(a b c d e f)\n" (with-out-str (binding [*print-length* 8] (pprint '(a b c d e f))))))
81+
82+
;; Vectors
83+
(is (= "[1 ...]\n" (with-out-str (binding [*print-length* 1] (pprint [1 2 3 4 5 6])))))
84+
(is (= "[1 2 ...]\n" (with-out-str (binding [*print-length* 2] (pprint [1 2 3 4 5 6])))))
85+
(is (= "[1 2 3 4 5 6]\n" (with-out-str (binding [*print-length* 6] (pprint [1 2 3 4 5 6])))))
86+
(is (= "[1 2 3 4 5 6]\n" (with-out-str (binding [*print-length* 8] (pprint [1 2 3 4 5 6])))))
87+
88+
;; CLJW: upstream uses sorted-set for deterministic order.
89+
;; CW sets have deterministic insertion order, so use small sets.
90+
;; Sets
91+
(is (= "#{1 ...}\n" (with-out-str (binding [*print-length* 1] (pprint #{1 2 3 4 5 6})))))
92+
(is (= "#{1 2 ...}\n" (with-out-str (binding [*print-length* 2] (pprint #{1 2 3 4 5 6})))))
93+
94+
;; CLJW: upstream uses sorted-map for deterministic order.
95+
;; CW maps have insertion order, so use small maps.
96+
;; Maps
97+
(is (= "{:a 1, ...}\n" (with-out-str (binding [*print-length* 1] (pprint {:a 1 :b 2 :c 3})))))
98+
(is (= "{:a 1, :b 2, ...}\n" (with-out-str (binding [*print-length* 2] (pprint {:a 1 :b 2 :c 3})))))
99+
(is (= "{:a 1, :b 2, :c 3}\n" (with-out-str (binding [*print-length* 3] (pprint {:a 1 :b 2 :c 3})))))
100+
(is (= "{:a 1, :b 2, :c 3}\n" (with-out-str (binding [*print-length* 8] (pprint {:a 1 :b 2 :c 3}))))))
101+
102+
;; CLJW: upstream also tests int-array with print-length.
103+
;; CW arrays are vectors, already tested above.
104+
105+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106+
;;; print-level-tests — *print-level* interaction with pprint
107+
;;; CLJW-ADD: upstream does not have explicit print-level tests for pprint,
108+
;;; but CW supports it. Adding tests for completeness.
109+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
110+
111+
(deftest print-level-tests
112+
(is (= "[1 [2 [3 #]]]\n"
113+
(with-out-str (binding [*print-level* 3] (pprint [1 [2 [3 [4 [5]]]]])))))
114+
(is (= "[1 [2 #]]\n"
115+
(with-out-str (binding [*print-level* 2] (pprint [1 [2 [3 [4 [5]]]]])))))
116+
(is (= "[1 #]\n"
117+
(with-out-str (binding [*print-level* 1] (pprint [1 [2 [3 [4 [5]]]]])))))
118+
(is (= "#\n"
119+
(with-out-str (binding [*print-level* 0] (pprint [1 [2 [3 [4 [5]]]]])))))
120+
;; print-level with lists
121+
(is (= "(1 (2 #))\n"
122+
(with-out-str (binding [*print-level* 2] (pprint '(1 (2 (3 (4)))))))))
123+
;; print-level with maps
124+
(is (= "{:a #}\n"
125+
(with-out-str (binding [*print-level* 1] (pprint {:a {:b {:c 1}}}))))))
126+
127+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
128+
;;; pprint-datastructures-tests — reference types through pprint
129+
;;; CLJW: upstream tests future-filled/unfilled, promise-filled/unfilled,
130+
;;; agent, atom, ref, delay-forced/unforced, defrecord, PersistentQueue.
131+
;;; CW tests atom, delay (forced/unforced), agent.
132+
;;; CW formats: #<atom ...>, #delay[...], #agent[...] (not JVM @hex format).
133+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134+
135+
(deftest pprint-datastructures-tests
136+
;; Atom
137+
(is (= "#<atom 42>\n" (with-out-str (pprint (atom 42)))))
138+
(is (= "#<atom {:x 1, :y 2}>\n" (with-out-str (pprint (atom {:x 1 :y 2})))))
139+
140+
;; Delay — forced
141+
;; CLJW: CW uses #delay[value] format instead of #<Delay@hex: value>
142+
(let [d (delay (+ 1 2))]
143+
(force d)
144+
(is (= "#delay[3]\n" (with-out-str (pprint d)))))
145+
146+
;; Delay — unforced
147+
;; CLJW: CW uses #delay[pending] instead of #<Delay@hex: :pending>
148+
(let [d (delay (+ 1 2))]
149+
(is (= "#delay[pending]\n" (with-out-str (pprint d)))))
150+
151+
;; Agent
152+
;; CLJW: CW uses #agent[value] format instead of #<Agent@hex: value>
153+
(let [a (agent '(first second third))]
154+
(is (= "#agent[(first second third)]\n" (with-out-str (pprint a))))))
155+
156+
;; CLJW: future, promise, ref, defrecord, PersistentQueue not tested.
157+
;; future/promise: CW has them but format differs.
158+
;; ref: CW does not implement STM refs.
159+
;; PersistentQueue: CW does not have clojure.lang.PersistentQueue/EMPTY.
160+
161+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
162+
;;; pprint-wrapping-test — multi-line wrapping behavior
163+
;;; CLJW-ADD: tests CW-specific wrapping at 72-column right margin.
164+
;;; Upstream tests wrapping with *print-right-margin* binding.
165+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
166+
167+
(deftest pprint-wrapping-test
168+
;; Short collections stay on one line
169+
(is (= "[1 2 3]\n" (with-out-str (pprint [1 2 3]))))
170+
(is (= "(a b c)\n" (with-out-str (pprint '(a b c)))))
171+
(is (= "{:a 1, :b 2}\n" (with-out-str (pprint {:a 1 :b 2}))))
172+
(is (= "#{1 2 3}\n" (with-out-str (pprint #{1 2 3}))))
173+
174+
;; Long vector wraps to multiple lines (default 72 col margin)
175+
;; CLJW: 50-element vector exceeds 72 columns, wraps with 1-space indent after [
176+
(let [result (with-out-str (pprint (vec (range 50))))]
177+
(is (.contains result "\n") "Long vector should wrap")
178+
(is (.startsWith result "[0") "Should start with [0")
179+
(is (.endsWith result "49]\n") "Should end with 49]"))
180+
181+
;; Long list wraps
182+
;; CLJW: 20-element list is under 72 cols, stays on one line
183+
(is (= "(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)\n"
184+
(with-out-str (pprint (range 20))))))
185+
186+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
187+
;;; pprint-empty-collections-test — empty collections
188+
;;; CLJW-ADD: verify pprint handles empty collections correctly.
189+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190+
191+
(deftest pprint-empty-collections-test
192+
(is (= "[]\n" (with-out-str (pprint []))))
193+
(is (= "()\n" (with-out-str (pprint '()))))
194+
(is (= "{}\n" (with-out-str (pprint {}))))
195+
(is (= "#{}\n" (with-out-str (pprint #{})))))
196+
197+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198+
;;; pprint-strings-test — string values through pprint
199+
;;; CLJW-ADD: verify pprint correctly quotes and escapes strings.
200+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201+
202+
(deftest pprint-strings-test
203+
(is (= "\"hello\"\n" (with-out-str (pprint "hello"))))
204+
(is (= "\"hello\\nworld\"\n" (with-out-str (pprint "hello\nworld"))))
205+
(is (= "\"tab\\there\"\n" (with-out-str (pprint "tab\there"))))
206+
(is (= "\"\"\n" (with-out-str (pprint "")))))
207+
208+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
209+
;;; pprint-nested-test — nested structures
210+
;;; CLJW-ADD: verify pprint handles nested structures correctly.
211+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
212+
213+
(deftest pprint-nested-test
214+
;; Nested map (short — single line)
215+
(is (= "{:a [1 2 3], :b {:c 4}}\n"
216+
(with-out-str (pprint {:a [1 2 3] :b {:c 4}}))))
217+
218+
;; Nested vector (short — single line)
219+
(is (= "[[1 2] [3 4] [5 6]]\n"
220+
(with-out-str (pprint [[1 2] [3 4] [5 6]]))))
221+
222+
;; Mixed types in collection
223+
(is (= "[1 \"two\" :three nil true]\n"
224+
(with-out-str (pprint [1 "two" :three nil true])))))
225+
226+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
227+
;;; print-table-test — print-table function
228+
;;; CLJW: upstream does not have print-table tests in test_pretty.clj.
229+
;;; CLJW-ADD: CW has print-table in clojure.pprint, testing it here.
230+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
231+
232+
(deftest print-table-test
233+
;; Basic print-table with auto-detected keys
234+
(let [result (with-out-str (print-table [{:a 1 :b 2} {:a 3 :b 4}]))]
235+
(is (.contains result "| :a | :b |"))
236+
(is (.contains result "|----+----|"))
237+
(is (.contains result "| 1 | 2 |"))
238+
(is (.contains result "| 3 | 4 |")))
239+
240+
;; print-table with explicit keys
241+
(let [result (with-out-str (print-table [:name :age]
242+
[{:name "Alice" :age 30}
243+
{:name "Bob" :age 25}]))]
244+
(is (.contains result ":name"))
245+
(is (.contains result ":age"))
246+
(is (.contains result "Alice"))
247+
(is (.contains result "Bob"))
248+
(is (.contains result "30"))
249+
(is (.contains result "25")))
250+
251+
;; print-table with wider columns
252+
(let [result (with-out-str (print-table [:name :city]
253+
[{:name "Charlie" :city "Kyoto"}]))]
254+
(is (.contains result "Charlie"))
255+
(is (.contains result "Kyoto")))
256+
257+
;; CLJW: print-table with empty rows returns nil (no output)
258+
(is (= "" (with-out-str (print-table [])))))
259+
260+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261+
;;; pprint-special-values-test — special numeric and symbolic values
262+
;;; CLJW-ADD: verify pprint handles special values.
263+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264+
265+
(deftest pprint-special-values-test
266+
;; Special float values
267+
(is (= "##Inf\n" (with-out-str (pprint ##Inf))))
268+
(is (= "##-Inf\n" (with-out-str (pprint ##-Inf))))
269+
(is (= "##NaN\n" (with-out-str (pprint ##NaN))))
270+
271+
;; Ratios
272+
(is (= "1/3\n" (with-out-str (pprint 1/3))))
273+
(is (= "22/7\n" (with-out-str (pprint 22/7))))
274+
275+
;; BigDecimal
276+
(is (= "3.14M\n" (with-out-str (pprint 3.14M))))
277+
278+
;; BigInt
279+
(is (= "99999999999999999999N\n" (with-out-str (pprint 99999999999999999999N)))))
280+
281+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
282+
;;; pprint-print-length-and-level-combined — combined *print-length* + *print-level*
283+
;;; CLJW-ADD: verify interaction of both controls.
284+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
285+
286+
(deftest pprint-print-length-and-level-combined
287+
;; Both print-length and print-level
288+
(is (= "[1 ...]\n"
289+
(with-out-str (binding [*print-length* 1 *print-level* 1]
290+
(pprint [1 [2 [3]]])))))
291+
(is (= "[1 #]\n"
292+
(with-out-str (binding [*print-length* 3 *print-level* 1]
293+
(pprint [1 [2 [3]]]))))))
294+
295+
(run-tests)

0 commit comments

Comments
 (0)