Skip to content

Commit

Permalink
Use clojure.test for generative tests
Browse files Browse the repository at this point in the history
  • Loading branch information
eerohele committed Oct 31, 2023
1 parent 8e1a68f commit 03c4c83
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 102 deletions.
102 changes: 0 additions & 102 deletions repl/check/pp.repl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

(require '[clojure.pprint :as cpp])
(require '[clojure.spec.alpha :as spec])
(require '[clojure.test.check :refer [quick-check]])
(require '[clojure.test.check.generators :as gen])
(require '[clojure.test.check.properties :refer [for-all]])

(require '[me.flowthing.pp :as pp])

Expand All @@ -14,105 +11,6 @@
(set! *print-length* nil)
(set! *print-level* nil)

;; Prints readably
(quick-check 10000
(for-all [x gen/any-printable-equatable
print-dup gen/boolean]
(= x
(read-string
(with-out-str
(binding [*print-dup* print-dup] (pp/pprint x)))))))

(xr/check! ::ret)

;; With infinite max width, prints everything the same way as prn.
(quick-check 10000
(for-all [x gen/any-printable-equatable]
(=
(with-out-str (pp/pprint x {:max-width ##Inf}))
(with-out-str (prn x)))))

(xr/check! ::ret)

;; TODO: Generative test that checks that nothing gets printed past
;; :max-width except strings? Not sure how easy it is to check whether
;; the thing past max-width is within a string, though.

(quick-check 1000
(for-all [print-level gen/nat
print-length gen/nat
x (gen/vector gen/int)]
(binding [*print-level* print-level
*print-length* print-length]
(= (with-out-str (pp/pprint x)) (with-out-str (cpp/pprint x))))))

(xr/check! ::ret)

;; Prints basic maps the same way as clojure.pprint/pprint.
(quick-check 1000
(for-all [print-length gen/nat
print-level gen/nat
x (gen/map gen/keyword gen/int)]
(binding [*print-level* print-level
*print-length* print-length]
(= (with-out-str (pp/pprint x)) (with-out-str (cpp/pprint x))))))

(xr/check! ::ret)

(quick-check 1000
(for-all [print-length gen/nat
print-level gen/nat
print-namespace-maps gen/boolean
x (gen/map gen/keyword-ns gen/int)]
(binding [*print-level* print-level
*print-length* print-length
*print-namespace-maps* print-namespace-maps]
(= (with-out-str (pp/pprint x)) (with-out-str (cpp/pprint x))))))

(xr/check! ::ret)

(quick-check 75
(for-all [print-namespace-maps gen/boolean
x (gen/map (gen/one-of [gen/keyword-ns gen/symbol-ns])
gen/any-printable-equatable)]
(binding [*print-namespace-maps* print-namespace-maps]
(=
(with-out-str
(pp/pprint x {:max-width ##Inf}))
(with-out-str
(binding [cpp/*print-right-margin* ##Inf]
(cpp/pprint x)))))))

(xr/check! ::ret)

;; A generative test that checks that pp/print and cpp/print print any
;; gen/any-printable-equatable the same way would be great, but
;; cpp/print sometimes prints things in miser mode even when there's
;; enough space to use linear mode, and I don't want to have my impl do
;; that.
;;
;; With infinite max width, however, me.flowthing.pp prints everything
;; the same way as clojure.pprint.
(quick-check 1000
(for-all [x gen/any-printable-equatable]
(binding [cpp/*print-right-margin* ##Inf]
(=
(with-out-str (pp/pprint x {:max-width ##Inf}))
(with-out-str (cpp/pprint x))))))

(xr/check! ::ret)

;; *print-readably*
(quick-check 1000
(for-all [x (gen/one-of [gen/string (gen/vector gen/char)])
print-readably gen/boolean]
(binding [*print-readably* print-readably]
(=
(with-out-str (pp/pprint x))
(with-out-str (cpp/pprint x))))))

(xr/check! ::ret)

(require '[clojure.repl :as repl])

(def clojure-core-sources
Expand Down
82 changes: 82 additions & 0 deletions test/me/flowthing/pp_test.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
(ns me.flowthing.pp-test
(:require [clojure.pprint :as cpp]
[clojure.test :refer [deftest is]]
[clojure.test.check.clojure-test :refer [defspec]]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :refer [for-all]]
[time-literals.read-write :as time-literals]
[me.flowthing.pp :as sut]))

Expand Down Expand Up @@ -248,3 +251,82 @@
(java.util.UUID/randomUUID)
(->R 1)]]
(is (= (str (print-str x) \newline) (pp-str x))))))

(defspec roundtrip 10000
(for-all [x gen/any-printable-equatable
print-dup gen/boolean]
(= x
(read-string
(with-out-str
(binding [*print-length* nil
*print-level* nil
*print-dup* print-dup]
(sut/pprint x)))))))

;; With infinite max width, prints everything the same way as prn.
(defspec print-linear 10000
(for-all [x gen/any-printable-equatable]
(=
(with-out-str (sut/pprint x {:max-width ##Inf}))
(with-out-str (prn x)))))

(defspec pp-vs-cpp-vec 1000
(for-all [print-level gen/nat
print-length gen/nat
x (gen/vector gen/int)]
(binding [*print-level* print-level
*print-length* print-length]
(= (with-out-str (sut/pprint x)) (with-out-str (cpp/pprint x))))))

(defspec pp-vs-cpp-map-1 1000
(for-all [print-length gen/nat
print-level gen/nat
x (gen/map gen/keyword gen/int)]
(binding [*print-level* print-level
*print-length* print-length]
(= (with-out-str (sut/pprint x)) (with-out-str (cpp/pprint x))))))

(defspec pp-vs-cpp-map-2 1000
(for-all [print-length gen/nat
print-level gen/nat
print-namespace-maps gen/boolean
x (gen/map gen/keyword-ns gen/int)]
(binding [*print-level* print-level
*print-length* print-length
*print-namespace-maps* print-namespace-maps]
(= (with-out-str (sut/pprint x)) (with-out-str (cpp/pprint x))))))

(defspec pp-vs-cpp-map-3 75
(for-all [print-namespace-maps gen/boolean
x (gen/map (gen/one-of [gen/keyword-ns gen/symbol-ns])
gen/any-printable-equatable)]
(binding [*print-namespace-maps* print-namespace-maps]
(=
(with-out-str
(sut/pprint x {:max-width ##Inf}))
(with-out-str
(binding [cpp/*print-right-margin* ##Inf]
(cpp/pprint x)))))))

;; A generative test that checks that pp/print and cpp/print print any
;; gen/any-printable-equatable the same way would be great, but
;; cpp/print sometimes prints things in miser mode even when there's
;; enough space to use linear mode, and I don't want to have my impl do
;; that.
;;
;; With infinite max width, however, me.flowthing.pp prints everything
;; the same way as clojure.pprint.
(defspec pp-vs-cpp-inf-max-with 1000
(for-all [x gen/any-printable-equatable]
(binding [cpp/*print-right-margin* ##Inf]
(=
(with-out-str (sut/pprint x {:max-width ##Inf}))
(with-out-str (cpp/pprint x))))))

(defspec print-readably 1000
(for-all [x (gen/one-of [gen/string (gen/vector gen/char)])
print-readably gen/boolean]
(binding [*print-readably* print-readably]
(=
(with-out-str (sut/pprint x))
(with-out-str (cpp/pprint x))))))

0 comments on commit 03c4c83

Please sign in to comment.