File: generators.clj

package info (click to toggle)
clojure1.6 1.6.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,608 kB
  • ctags: 5,838
  • sloc: java: 27,336; xml: 498; sh: 69; makefile: 45
file content (132 lines) | stat: -rw-r--r-- 3,185 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
(ns clojure.test-clojure.generators
  (:require [clojure.data.generators :as gen])
  (:refer-clojure :exclude [namespace]))

(defn var-value-source
  "Generates a scalar suitable for an initial var value."
  []
  (let [v (gen/scalar)]
    (if (symbol? v)
      `(quote ~v)
      v)))

(defn var-source
  [n]
  `(def ~(symbol (str "var" n))
     ~(var-value-source)))

(defn record-source
  [n]
  (let [rname (str "ExampleRecord" "-" n)
        fldct (gen/geometric 0.1)]
    `(defrecord ~(symbol rname) ~(vec (map #(symbol (str "f" %)) (range fldct))))))

(defn generate-namespaces
  "Returns a map with :nses, :vars, :records"
  [{:keys [nses vars-per-ns records-per-ns]}]
  (let [nses (mapv #(create-ns (symbol (str "clojure.generated.ns" %)))
                   (range nses))
        _ (doseq [ns nses] (binding [*ns* ns] (refer 'clojure.core)))
        make-in-ns (fn [ns src] (binding [*ns* ns] (eval src)))
        vars (->> (mapcat
                   (fn [ns]
                     (map
                      #(make-in-ns ns (var-source %))
                      (range vars-per-ns)))
                   nses)
                  (into []))
        records (->> (mapcat
                      (fn [ns]
                        (map
                         #(make-in-ns ns (record-source %))
                         (range records-per-ns)))
                      nses)
                     (into []))]
    {:nses nses
     :vars vars
     :records records}))

(def shared-generation
  (delay (generate-namespaces {:nses 5 :vars-per-ns 5 :records-per-ns 5})))

(defn namespace
  []
  (gen/rand-nth (:nses @shared-generation)))

(defn var
  []
  (gen/rand-nth (:vars @shared-generation)))

(defn record
  []
  (gen/rand-nth (:records @shared-generation)))

(def keyword-pool
  (delay
   (binding [gen/*rnd* (java.util.Random. 42)]
     (into [] (repeatedly 1000 gen/keyword)))))

(defn keyword-from-pool
  []
  (gen/rand-nth @keyword-pool))

(def symbol-pool
  (delay
   (binding [gen/*rnd* (java.util.Random. 42)]
     (into [] (repeatedly 1000 gen/symbol)))))

(defn symbol-from-pool
  []
  (gen/rand-nth @keyword-pool))

(def ednable-scalars
  [(constantly nil)
   gen/byte
   gen/long
   gen/boolean
   gen/printable-ascii-char
   gen/string
   symbol-from-pool
   keyword-from-pool
   gen/uuid
   gen/date
   gen/ratio
   gen/bigint
   gen/bigdec])

(defn- call-through
  "Recursively call x until it doesn't return a function."
  [x]
  (if (fn? x)
    (recur (x))
    x))

(defn ednable-scalar
  []
  (call-through (rand-nth ednable-scalars)))

(def ednable-collections
  [[gen/vec [ednable-scalars]]
   [gen/set [ednable-scalars]]
   [gen/hash-map [ednable-scalars ednable-scalars]]])

(defn ednable-collection
  []
  (let [[coll args] (rand-nth ednable-collections)]
    (apply coll (map rand-nth args))))

(defn ednable
  []
  (gen/one-of ednable-scalar ednable-collection))

(defn non-ednable
  "Generate something that can be printed with *print-dup*, but
   cannot be read back via edn/read."
  []
  (gen/one-of namespace var))

(defn dup-readable
  "Generate something that requires print-dup to be printed in
   a roundtrippable way."
  []
  (gen/one-of namespace var))