File: gen_fn_adapter_tests.clj

package info (click to toggle)
clojure 1.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,704 kB
  • sloc: java: 43,177; xml: 599; sh: 68; makefile: 50
file content (177 lines) | stat: -rw-r--r-- 8,178 bytes parent folder | download
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;; This code was used to generate:
;;     generated_all_fi_adapters_in_let.clj
;;     generated_functional_adapters_in_def_requiring_reflection.clj
;;     generated_functional_adapters_in_def.clj
;;     AdapterExerciser.java
;; This code is not intended to be reused but might be
;; useful in the future as a template for other code gen.

(ns gen-fn-adapter-tests
  (:require
    [clojure.string :as str])
  (:import
    [java.io StringWriter Writer]))

(defn let-test-header [imported-methods]
      (format "
(ns clojure.test-clojure.generated-all-fi-adapters-in-let
  (:use clojure.test)
  (:require [clojure.string :as str])
  (:import (clojure.test AdapterExerciser %s)))

  (deftest test-all-fi-adapters-in-let
    (let [^AdapterExerciser exerciser (AdapterExerciser.)" imported-methods))

(defn def-test-header [filename]
      (format "
(ns clojure.test-clojure.%s
  (:use clojure.test)
  (:require [clojure.string :as str])
  (:import (clojure.test AdapterExerciser)))

  (deftest functional-adapters-in-def
           (def exerciser (AdapterExerciser.))" filename))

(def adapter-exerciser-header "
package clojure.test;

public class AdapterExerciser {")

(defn sigs [args return-types]
      (let [fun-sig-reducer (fn [res ret]
                                (mapcat seq [res (map (fn [params]
                                                          (str params ret)) args)]))]
           (reduce fun-sig-reducer [] return-types)))

(defn gen-sigs []
      (let [small-rets ["L" "I" "S" "B" "D" "F" "O"]
            zero-arity (sigs [""] small-rets)
            single-arity (sigs ["L" "D" "O"] small-rets)
            two-arity (sigs ["LL" "LO" "OL" "DD" "LD" "DL" "OO" "OD" "DO"] small-rets)
            big-rets ["O"]
            three-arity (sigs ["OOO"] big-rets)
            four-arity  (sigs ["OOOO"] big-rets)
            five-arity  (sigs ["OOOOO"] big-rets)
            six-arity   (sigs ["OOOOOO"] big-rets)
            seven-arity (sigs ["OOOOOOO"] big-rets)
            eight-arity (sigs ["OOOOOOOO"] big-rets)
            nine-arity  (sigs ["OOOOOOOOO"] big-rets)
            ten-arity   (sigs ["OOOOOOOOOO"] big-rets)]
           (mapcat seq [zero-arity single-arity two-arity three-arity four-arity five-arity six-arity seven-arity eight-arity nine-arity ten-arity])))

(def alphabet (map char (range 97 122)))
(def type-hints {:D "^double "
                 :O "^AdapterExerciser "
                 :L "^long "
                 :I "^int "
                 :F "^float "
                 :Z "^boolean "
                 :S "^short "
                 :B "^byte "})
(def types {:D "double"
            :O "AdapterExerciser"
            :L "long"
            :I "int"
            :F "float"
            :Z "boolean"
            :S "short"
            :B "byte"})
(def method-args {:D "(double 1)"
                  :O "exerciser"
                  :L "(long 1)"
                  :I "1"
                  :F "(float 1)"
                  :Z "false"
                  :S "(short 1)"
                  :B "(byte 1)"})

(defn format-parts [sig]
      (let [return-type-initial (str (last sig))
            return-type (get types (keyword return-type-initial))
            input-types (map str (butlast sig))
            arg-type-hints (map #(get type-hints (keyword %)) input-types)
            java-types (map #(get types (keyword %)) input-types)
            fn-vars (str/join " " (map #(str %1 %2) arg-type-hints (take (count input-types) alphabet)))
            fn-args (str/join " " (map #(get method-args (keyword %)) input-types))
            java-vars (str/join ", " (map #(str %1 " " %2) java-types (take (count input-types) alphabet)))
            fn-body (get method-args (keyword return-type-initial))
            expected-val (get method-args (keyword return-type-initial))]
           {:return-type return-type :fn-args fn-args :return-type-initial return-type-initial :fn-vars fn-vars :fn-body fn-body :input-types input-types :java-vars java-vars :expected-val expected-val}))

(defn gen-imported-methods [sigs]
      (let [sb (StringBuilder. " ")]
           (doseq [sig sigs]
                  (.append sb (format "AdapterExerciser$%s" sig))
                  (.append sb "\n"))
           (.toString sb)))

(defn gen-test-all-fi-adapters-in-let []
      (let [adapter-signatures (gen-sigs)
            imported-methods (gen-imported-methods adapter-signatures)
            sb (StringBuilder. ^String (let-test-header imported-methods))]
           ;; Assemble let
           (doseq [sig adapter-signatures]
                  (let [{:keys [fn-vars fn-body]} (format-parts sig)]
                       (.append sb "\n")
                       (.append sb (format "          ^AdapterExerciser$%s %sadapter (fn [%s] %s)" sig sig fn-vars fn-body))))
           (.append sb "]")
           ;; Assemble test cases
           (doseq [sig adapter-signatures]
                  (let [{:keys [return-type-initial fn-args expected-val]} (format-parts sig)]
                       (.append sb "\n")
                       (.append sb (format "      (is (= (.takes%sRet%s %sadapter %s) %s))" (str/join "" (butlast sig)) return-type-initial sig fn-args expected-val))))
           (.append sb "))")
           (spit "generated_all_fi_adapters_in_let.clj" (.toString sb))))

(defn gen-test-functional-adapters-in-def []
      (let [sb (StringBuilder. ^String (def-test-header "generated-functional-adapters-in-def"))
            adapter-signatures (gen-sigs)]
           (doseq [sig adapter-signatures]
                  (let [{:keys [fn-vars fn-body]} (format-parts sig)]
                       (.append sb "\n")
                       (.append sb (format "           (def %sadapter (fn [%s] %s))" sig fn-vars fn-body))
                       (.append sb "\n")
                       (.append sb (format "           (is (= (.method%s ^AdapterExerciser exerciser %sadapter) %s))" sig sig (str "\"" sig "\"")))))
           (.append sb ")")
           (spit "generated_functional_adapters_in_def.clj" (.toString sb))))

(defn gen-test-functional-adapters-in-def-requiring-reflection []
      (let [sb (StringBuilder. ^String (def-test-header "generated-functional-adapters-in-def-requiring-reflection"))
            adapter-signatures (gen-sigs)]
           (doseq [sig adapter-signatures]
                  (let [{:keys [fn-vars fn-body]} (format-parts sig)]
                       (.append sb "\n")
                       (.append sb (format "           (def %sadapter (fn [%s] %s))" sig fn-vars fn-body))
                       (.append sb "\n")
                       (.append sb (format "           (is (= (.method%s exerciser %sadapter) %s))" sig sig (str "\"" sig "\"")))))
           (.append sb ")")
           (spit "generated_functional_adapters_in_def_requiring_reflection.clj" (.toString sb))))

(defn gen-adapter-exerciser-class []
      (let [sb (StringBuilder. ^String adapter-exerciser-header)
            adapter-signatures (gen-sigs)]
           (doseq [sig adapter-signatures]
                  (let [{:keys [return-type return-type-initial input-types java-vars]} (format-parts sig)]
                       (.append sb "\n")
                       (.append sb "    @FunctionalInterface\n")
                       (.append sb (format "    public interface %s {\n" sig))
                       (.append sb (format "        public %s takes%sRet%s(%s);\n" return-type (str/join "" input-types) return-type-initial java-vars))
                       (.append sb "    }")))
           (doseq [sig adapter-signatures]
                  (.append sb "\n")
                  (.append sb (format "   public String method%s(%s a) { return %s; }" sig sig (str "\"" sig "\""))))
           (.append sb "}")
           (spit "AdapterExerciser.java" (.toString sb))))

(defn gen-all []
  (gen-test-all-fi-adapters-in-let)
  (gen-test-functional-adapters-in-def)
  (gen-test-functional-adapters-in-def-requiring-reflection)
  (gen-adapter-exerciser-class))

(comment
  (gen-all)
  (gen-test-all-fi-adapters-in-let)
  (gen-test-functional-adapters-in-def)
  (gen-test-functional-adapters-in-def-requiring-reflection)
  (gen-adapter-exerciser-class))