annotate src/clojure/test_clojure/serialization.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 ; Copyright (c) Rich Hickey. All rights reserved.
rlm@10 2 ; The use and distribution terms for this software are covered by the
rlm@10 3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 4 ; which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 5 ; By using this software in any fashion, you are agreeing to be bound by
rlm@10 6 ; the terms of this license.
rlm@10 7 ; You must not remove this notice, or any other, from this software.
rlm@10 8
rlm@10 9 ;; Author: Chas Emerick
rlm@10 10 ;; cemerick@snowtide.com
rlm@10 11
rlm@10 12 (ns clojure.test-clojure.serialization
rlm@10 13 (:use clojure.test)
rlm@10 14 (:import (java.io ObjectOutputStream ObjectInputStream
rlm@10 15 ByteArrayOutputStream ByteArrayInputStream)))
rlm@10 16
rlm@10 17 (defn- serialize
rlm@10 18 "Serializes a single object, returning a byte array."
rlm@10 19 [v]
rlm@10 20 (with-open [bout (ByteArrayOutputStream.)
rlm@10 21 oos (ObjectOutputStream. bout)]
rlm@10 22 (.writeObject oos v)
rlm@10 23 (.flush oos)
rlm@10 24 (.toByteArray bout)))
rlm@10 25
rlm@10 26 (defn- deserialize
rlm@10 27 "Deserializes and returns a single object from the given byte array."
rlm@10 28 [bytes]
rlm@10 29 (with-open [ois (-> bytes ByteArrayInputStream. ObjectInputStream.)]
rlm@10 30 (.readObject ois)))
rlm@10 31
rlm@10 32 (defrecord SerializationRecord [a b c])
rlm@10 33 (defstruct SerializationStruct :a :b :c)
rlm@10 34
rlm@10 35 (defn- build-via-transient
rlm@10 36 [coll]
rlm@10 37 (persistent!
rlm@10 38 (reduce conj! (transient coll) (map vec (partition 2 (range 1000))))))
rlm@10 39
rlm@10 40 (defn- roundtrip
rlm@10 41 [v]
rlm@10 42 (let [rt (-> v serialize deserialize)
rlm@10 43 rt-seq (-> v seq serialize deserialize)]
rlm@10 44 (and (= v rt)
rlm@10 45 (= (seq v) (seq rt))
rlm@10 46 (= (seq v) rt-seq))))
rlm@10 47
rlm@10 48 (deftest sequable-serialization
rlm@10 49 (are [val] (roundtrip val)
rlm@10 50 ; lists and related
rlm@10 51 (list)
rlm@10 52 (apply list (range 10))
rlm@10 53 (cons 0 nil)
rlm@10 54 (clojure.lang.Cons. 0 nil)
rlm@10 55
rlm@10 56 ; vectors
rlm@10 57 []
rlm@10 58 (into [] (range 10))
rlm@10 59 (into [] (range 25))
rlm@10 60 (into [] (range 100))
rlm@10 61 (into [] (range 500))
rlm@10 62 (into [] (range 1000))
rlm@10 63
rlm@10 64 ; maps
rlm@10 65 {}
rlm@10 66 {:a 5 :b 0}
rlm@10 67 (apply array-map (range 100))
rlm@10 68 (apply hash-map (range 100))
rlm@10 69
rlm@10 70 ; sets
rlm@10 71 #{}
rlm@10 72 #{'a 'b 'c}
rlm@10 73 (set (range 10))
rlm@10 74 (set (range 25))
rlm@10 75 (set (range 100))
rlm@10 76 (set (range 500))
rlm@10 77 (set (range 1000))
rlm@10 78 (sorted-set)
rlm@10 79 (sorted-set 'a 'b 'c)
rlm@10 80 (apply sorted-set (reverse (range 10)))
rlm@10 81 (apply sorted-set (reverse (range 25)))
rlm@10 82 (apply sorted-set (reverse (range 100)))
rlm@10 83 (apply sorted-set (reverse (range 500)))
rlm@10 84 (apply sorted-set (reverse (range 1000)))
rlm@10 85
rlm@10 86 ; queues
rlm@10 87 clojure.lang.PersistentQueue/EMPTY
rlm@10 88 (into clojure.lang.PersistentQueue/EMPTY (range 50))
rlm@10 89
rlm@10 90 ; lazy seqs
rlm@10 91 (lazy-seq nil)
rlm@10 92 (lazy-seq (range 50))
rlm@10 93
rlm@10 94 ; transient / persistent! round-trip
rlm@10 95 (build-via-transient [])
rlm@10 96 (build-via-transient {})
rlm@10 97 (build-via-transient #{})
rlm@10 98
rlm@10 99 ; array-seqs
rlm@10 100 (seq (make-array Object 10))
rlm@10 101 (seq (make-array Boolean/TYPE 10))
rlm@10 102 (seq (make-array Byte/TYPE 10))
rlm@10 103 (seq (make-array Character/TYPE 10))
rlm@10 104 (seq (make-array Double/TYPE 10))
rlm@10 105 (seq (make-array Float/TYPE 10))
rlm@10 106 (seq (make-array Integer/TYPE 10))
rlm@10 107 (seq (make-array Long/TYPE 10))
rlm@10 108
rlm@10 109 ; "records"
rlm@10 110 (SerializationRecord. 0 :foo (range 20))
rlm@10 111 (struct SerializationStruct 0 :foo (range 20))
rlm@10 112
rlm@10 113 ; misc seqs
rlm@10 114 (seq "s11n")
rlm@10 115 (range 50)
rlm@10 116 (rseq (apply sorted-set (reverse (range 100))))))
rlm@10 117
rlm@10 118 (deftest misc-serialization
rlm@10 119 (are [v] (= v (-> v serialize deserialize))
rlm@10 120 25/3
rlm@10 121 :keyword
rlm@10 122 ::namespaced-keyword
rlm@10 123 'symbol))
rlm@10 124
rlm@10 125 (deftest interned-serializations
rlm@10 126 (are [v] (identical? v (-> v serialize deserialize))
rlm@10 127 clojure.lang.RT/DEFAULT_COMPARATOR
rlm@10 128
rlm@10 129 ; namespaces just get deserialized back into the same-named ns in the present runtime
rlm@10 130 ; (they're referred to by defrecord instances)
rlm@10 131 *ns*))
rlm@10 132
rlm@10 133 (deftest function-serialization
rlm@10 134 (let [capture 5]
rlm@10 135 (are [f] (= capture ((-> f serialize deserialize)))
rlm@10 136 (constantly 5)
rlm@10 137 (fn [] 5)
rlm@10 138 #(do 5)
rlm@10 139 (constantly capture)
rlm@10 140 (fn [] capture)
rlm@10 141 #(do capture))))
rlm@10 142
rlm@10 143 (deftest check-unserializable-objects
rlm@10 144 (are [t] (thrown? java.io.NotSerializableException (serialize t))
rlm@10 145 ;; transients
rlm@10 146 (transient [])
rlm@10 147 (transient {})
rlm@10 148 (transient #{})
rlm@10 149
rlm@10 150 ;; reference types
rlm@10 151 (atom nil)
rlm@10 152 (ref nil)
rlm@10 153 (agent nil)
rlm@10 154 #'+
rlm@10 155
rlm@10 156 ;; stateful seqs
rlm@10 157 (enumeration-seq (java.util.Collections/enumeration (range 50)))
rlm@10 158 (iterator-seq (.iterator (range 50)))))