annotate src/clojure/test_clojure/pprint/test_pretty.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;;; test_pretty.clj -- part of the pretty printer for Clojure
rlm@10 2
rlm@10 3 ; Copyright (c) Rich Hickey. All rights reserved.
rlm@10 4 ; The use and distribution terms for this software are covered by the
rlm@10 5 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 6 ; which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 7 ; By using this software in any fashion, you are agreeing to be bound by
rlm@10 8 ; the terms of this license.
rlm@10 9 ; You must not remove this notice, or any other, from this software.
rlm@10 10
rlm@10 11 ;; Author: Tom Faulhaber
rlm@10 12 ;; April 3, 2009
rlm@10 13
rlm@10 14
rlm@10 15 (in-ns 'clojure.test-clojure.pprint)
rlm@10 16
rlm@10 17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 18 ;;;
rlm@10 19 ;;; Unit tests for the pretty printer
rlm@10 20 ;;;
rlm@10 21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rlm@10 22
rlm@10 23 (simple-tests xp-fill-test
rlm@10 24 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 25 *print-right-margin* 38
rlm@10 26 *print-miser-width* nil]
rlm@10 27 (cl-format nil "(let ~:<~@{~:<~w ~_~w~:>~^ ~:_~}~:>~_ ...)~%"
rlm@10 28 '((x 4) (*print-length* nil) (z 2) (list nil))))
rlm@10 29 "(let ((x 4) (*print-length* nil)\n (z 2) (list nil))\n ...)\n"
rlm@10 30
rlm@10 31 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 32 *print-right-margin* 22]
rlm@10 33 (cl-format nil "(let ~:<~@{~:<~w ~_~w~:>~^ ~:_~}~:>~_ ...)~%"
rlm@10 34 '((x 4) (*print-length* nil) (z 2) (list nil))))
rlm@10 35 "(let ((x 4)\n (*print-length*\n nil)\n (z 2)\n (list nil))\n ...)\n")
rlm@10 36
rlm@10 37 (simple-tests xp-miser-test
rlm@10 38 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 39 *print-right-margin* 10, *print-miser-width* 9]
rlm@10 40 (cl-format nil "~:<LIST ~@_~W ~@_~W ~@_~W~:>" '(first second third)))
rlm@10 41 "(LIST\n first\n second\n third)"
rlm@10 42
rlm@10 43 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 44 *print-right-margin* 10, *print-miser-width* 8]
rlm@10 45 (cl-format nil "~:<LIST ~@_~W ~@_~W ~@_~W~:>" '(first second third)))
rlm@10 46 "(LIST first second third)")
rlm@10 47
rlm@10 48 (simple-tests mandatory-fill-test
rlm@10 49 (cl-format nil
rlm@10 50 "<pre>~%~<Usage: ~:I~@{*~a*~^~:@_~}~:>~%</pre>~%"
rlm@10 51 [ "hello" "gooodbye" ])
rlm@10 52 "<pre>
rlm@10 53 Usage: *hello*
rlm@10 54 *gooodbye*
rlm@10 55 </pre>
rlm@10 56 ")
rlm@10 57
rlm@10 58 (simple-tests prefix-suffix-test
rlm@10 59 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 60 *print-right-margin* 10, *print-miser-width* 10]
rlm@10 61 (cl-format nil "~<{~;LIST ~@_~W ~@_~W ~@_~W~;}~:>" '(first second third)))
rlm@10 62 "{LIST\n first\n second\n third}")
rlm@10 63
rlm@10 64 (simple-tests pprint-test
rlm@10 65 (binding [*print-pprint-dispatch* simple-dispatch]
rlm@10 66 (write '(defn foo [x y]
rlm@10 67 (let [result (* x y)]
rlm@10 68 (if (> result 400)
rlm@10 69 (cl-format true "That number is too big")
rlm@10 70 (cl-format true "The result of ~d x ~d is ~d" x y result))))
rlm@10 71 :stream nil))
rlm@10 72 "(defn
rlm@10 73 foo
rlm@10 74 [x y]
rlm@10 75 (let
rlm@10 76 [result (* x y)]
rlm@10 77 (if
rlm@10 78 (> result 400)
rlm@10 79 (cl-format true \"That number is too big\")
rlm@10 80 (cl-format true \"The result of ~d x ~d is ~d\" x y result))))"
rlm@10 81
rlm@10 82 (with-pprint-dispatch code-dispatch
rlm@10 83 (write '(defn foo [x y]
rlm@10 84 (let [result (* x y)]
rlm@10 85 (if (> result 400)
rlm@10 86 (cl-format true "That number is too big")
rlm@10 87 (cl-format true "The result of ~d x ~d is ~d" x y result))))
rlm@10 88 :stream nil))
rlm@10 89 "(defn foo [x y]
rlm@10 90 (let [result (* x y)]
rlm@10 91 (if (> result 400)
rlm@10 92 (cl-format true \"That number is too big\")
rlm@10 93 (cl-format true \"The result of ~d x ~d is ~d\" x y result))))"
rlm@10 94
rlm@10 95 (binding [*print-pprint-dispatch* simple-dispatch
rlm@10 96 *print-right-margin* 15]
rlm@10 97 (write '(fn (cons (car x) (cdr y))) :stream nil))
rlm@10 98 "(fn\n (cons\n (car x)\n (cdr y)))"
rlm@10 99
rlm@10 100 (with-pprint-dispatch code-dispatch
rlm@10 101 (binding [*print-right-margin* 52]
rlm@10 102 (write
rlm@10 103 '(add-to-buffer this (make-buffer-blob (str (char c)) nil))
rlm@10 104 :stream nil)))
rlm@10 105 "(add-to-buffer\n this\n (make-buffer-blob (str (char c)) nil))"
rlm@10 106 )
rlm@10 107
rlm@10 108
rlm@10 109
rlm@10 110 (simple-tests pprint-reader-macro-test
rlm@10 111 (with-pprint-dispatch code-dispatch
rlm@10 112 (write (read-string "(map #(first %) [[1 2 3] [4 5 6] [7]])")
rlm@10 113 :stream nil))
rlm@10 114 "(map #(first %) [[1 2 3] [4 5 6] [7]])"
rlm@10 115
rlm@10 116 (with-pprint-dispatch code-dispatch
rlm@10 117 (write (read-string "@@(ref (ref 1))")
rlm@10 118 :stream nil))
rlm@10 119 "@@(ref (ref 1))"
rlm@10 120
rlm@10 121 (with-pprint-dispatch code-dispatch
rlm@10 122 (write (read-string "'foo")
rlm@10 123 :stream nil))
rlm@10 124 "'foo"
rlm@10 125 )
rlm@10 126
rlm@10 127 (simple-tests code-block-tests
rlm@10 128 (with-out-str
rlm@10 129 (with-pprint-dispatch code-dispatch
rlm@10 130 (pprint
rlm@10 131 '(defn cl-format
rlm@10 132 "An implementation of a Common Lisp compatible format function"
rlm@10 133 [stream format-in & args]
rlm@10 134 (let [compiled-format (if (string? format-in) (compile-format format-in) format-in)
rlm@10 135 navigator (init-navigator args)]
rlm@10 136 (execute-format stream compiled-format navigator))))))
rlm@10 137 "(defn cl-format
rlm@10 138 \"An implementation of a Common Lisp compatible format function\"
rlm@10 139 [stream format-in & args]
rlm@10 140 (let [compiled-format (if (string? format-in)
rlm@10 141 (compile-format format-in)
rlm@10 142 format-in)
rlm@10 143 navigator (init-navigator args)]
rlm@10 144 (execute-format stream compiled-format navigator)))
rlm@10 145 "
rlm@10 146
rlm@10 147 (with-out-str
rlm@10 148 (with-pprint-dispatch code-dispatch
rlm@10 149 (pprint
rlm@10 150 '(defn pprint-defn [writer alis]
rlm@10 151 (if (next alis)
rlm@10 152 (let [[defn-sym defn-name & stuff] alis
rlm@10 153 [doc-str stuff] (if (string? (first stuff))
rlm@10 154 [(first stuff) (next stuff)]
rlm@10 155 [nil stuff])
rlm@10 156 [attr-map stuff] (if (map? (first stuff))
rlm@10 157 [(first stuff) (next stuff)]
rlm@10 158 [nil stuff])]
rlm@10 159 (pprint-logical-block writer :prefix "(" :suffix ")"
rlm@10 160 (cl-format true "~w ~1I~@_~w" defn-sym defn-name)
rlm@10 161 (if doc-str
rlm@10 162 (cl-format true " ~_~w" doc-str))
rlm@10 163 (if attr-map
rlm@10 164 (cl-format true " ~_~w" attr-map))
rlm@10 165 ;; Note: the multi-defn case will work OK for malformed defns too
rlm@10 166 (cond
rlm@10 167 (vector? (first stuff)) (single-defn stuff (or doc-str attr-map))
rlm@10 168 :else (multi-defn stuff (or doc-str attr-map)))))
rlm@10 169 (pprint-simple-code-list writer alis))))))
rlm@10 170 "(defn pprint-defn [writer alis]
rlm@10 171 (if (next alis)
rlm@10 172 (let [[defn-sym defn-name & stuff] alis
rlm@10 173 [doc-str stuff] (if (string? (first stuff))
rlm@10 174 [(first stuff) (next stuff)]
rlm@10 175 [nil stuff])
rlm@10 176 [attr-map stuff] (if (map? (first stuff))
rlm@10 177 [(first stuff) (next stuff)]
rlm@10 178 [nil stuff])]
rlm@10 179 (pprint-logical-block
rlm@10 180 writer
rlm@10 181 :prefix
rlm@10 182 \"(\"
rlm@10 183 :suffix
rlm@10 184 \")\"
rlm@10 185 (cl-format true \"~w ~1I~@_~w\" defn-sym defn-name)
rlm@10 186 (if doc-str (cl-format true \" ~_~w\" doc-str))
rlm@10 187 (if attr-map (cl-format true \" ~_~w\" attr-map))
rlm@10 188 (cond
rlm@10 189 (vector? (first stuff)) (single-defn
rlm@10 190 stuff
rlm@10 191 (or doc-str attr-map))
rlm@10 192 :else (multi-defn stuff (or doc-str attr-map)))))
rlm@10 193 (pprint-simple-code-list writer alis)))
rlm@10 194 ")
rlm@10 195
rlm@10 196
rlm@10 197 (defn tst-pprint
rlm@10 198 "A helper function to pprint to a string with a restricted right margin"
rlm@10 199 [right-margin obj]
rlm@10 200 (binding [*print-right-margin* right-margin
rlm@10 201 *print-pretty* true]
rlm@10 202 (write obj :stream nil)))
rlm@10 203
rlm@10 204 ;;; A bunch of predefined data to print
rlm@10 205 (def future-filled (future-call (fn [] 100)))
rlm@10 206 @future-filled
rlm@10 207 (def future-unfilled (future-call (fn [] (.acquire (java.util.concurrent.Semaphore. 0)))))
rlm@10 208 (def promise-filled (promise))
rlm@10 209 (deliver promise-filled '(first second third))
rlm@10 210 (def promise-unfilled (promise))
rlm@10 211 (def basic-agent (agent '(first second third)))
rlm@10 212 (defn failed-agent
rlm@10 213 "must be a fn because you cannot await agents during load"
rlm@10 214 []
rlm@10 215 (let [a (agent "foo")]
rlm@10 216 (send a +)
rlm@10 217 (try (await-for 100 failed-agent) (catch RuntimeException re))
rlm@10 218 a))
rlm@10 219 (def basic-atom (atom '(first second third)))
rlm@10 220 (def basic-ref (ref '(first second third)))
rlm@10 221 (def delay-forced (delay '(first second third)))
rlm@10 222 (force delay-forced)
rlm@10 223 (def delay-unforced (delay '(first second third)))
rlm@10 224 (defrecord pprint-test-rec [a b c])
rlm@10 225
rlm@10 226 (simple-tests pprint-datastructures-tests
rlm@10 227 (tst-pprint 20 future-filled) #"#<Future@[0-9a-f]+: \n 100>"
rlm@10 228 (tst-pprint 20 future-unfilled) #"#<Future@[0-9a-f]+: \n :pending>"
rlm@10 229 (tst-pprint 20 promise-filled) #"#<Promise@[0-9a-f]+: \n \(first\n second\n third\)>"
rlm@10 230 ;; This hangs currently, cause we can't figure out whether a promise is filled
rlm@10 231 ;;(tst-pprint 20 promise-unfilled) #"#<Promise@[0-9a-f]+: \n :pending>"
rlm@10 232 (tst-pprint 20 basic-agent) #"#<Agent@[0-9a-f]+: \n \(first\n second\n third\)>"
rlm@10 233 (tst-pprint 20 (failed-agent)) #"#<Agent@[0-9a-f]+ FAILED: \n \"foo\">"
rlm@10 234 (tst-pprint 20 basic-atom) #"#<Atom@[0-9a-f]+: \n \(first\n second\n third\)>"
rlm@10 235 (tst-pprint 20 basic-ref) #"#<Ref@[0-9a-f]+: \n \(first\n second\n third\)>"
rlm@10 236 (tst-pprint 20 delay-forced) #"#<Delay@[0-9a-f]+: \n \(first\n second\n third\)>"
rlm@10 237 ;; Currently no way not to force the delay
rlm@10 238 ;;(tst-pprint 20 delay-unforced) #"#<Delay@[0-9a-f]+: \n :pending>"
rlm@10 239 (tst-pprint 20 (pprint-test-rec. 'first 'second 'third)) "{:a first,\n :b second,\n :c third}"
rlm@10 240
rlm@10 241 ;; basic java arrays: fails owing to assembla ticket #346
rlm@10 242 ;;(tst-pprint 10 (int-array (range 7))) "[0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6]"
rlm@10 243 (tst-pprint 15 (reduce conj clojure.lang.PersistentQueue/EMPTY (range 10)))
rlm@10 244 "<-(0\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9)-<"
rlm@10 245 )
rlm@10 246
rlm@10 247
rlm@10 248 ;;; Some simple tests of dispatch
rlm@10 249
rlm@10 250 (defmulti
rlm@10 251 test-dispatch
rlm@10 252 "A test dispatch method"
rlm@10 253 {:added "1.2" :arglists '[[object]]}
rlm@10 254 #(and (seq %) (not (string? %))))
rlm@10 255
rlm@10 256 (defmethod test-dispatch true [avec]
rlm@10 257 (pprint-logical-block :prefix "[" :suffix "]"
rlm@10 258 (loop [aseq (seq avec)]
rlm@10 259 (when aseq
rlm@10 260 (write-out (first aseq))
rlm@10 261 (when (next aseq)
rlm@10 262 (.write ^java.io.Writer *out* " ")
rlm@10 263 (pprint-newline :linear)
rlm@10 264 (recur (next aseq)))))))
rlm@10 265
rlm@10 266 (defmethod test-dispatch false [aval] (pr aval))
rlm@10 267
rlm@10 268 (simple-tests dispatch-tests
rlm@10 269 (with-pprint-dispatch test-dispatch
rlm@10 270 (with-out-str
rlm@10 271 (pprint '("hello" "there"))))
rlm@10 272 "[\"hello\" \"there\"]\n"
rlm@10 273 )
rlm@10 274
rlm@10 275