 
   (is (== 42.2e3M (read-string "42.2e3M")))
   (is (== +42.2e+3M (read-string "+42.2e+3M")))
-  (is (== -42.2e-3M (read-string "-42.2e-3M"))))
+  (is (== -42.2e-3M (read-string "-42.2e-3M")))
+
+  (is (instance? Double (read-string "+1.0e+1")))
+  (is (instance? Double (read-string "+1.e+1")))
+  (is (instance? Double (read-string "+1e+1")))
+
+  (is (instance? Double (read-string "+1.0e+1")))
+  (is (instance? Double (read-string "+1.e+1")))
+  (is (instance? Double (read-string "+1e+1")))
+
+  (is (instance? Double (read-string "+1.0e1")))
+  (is (instance? Double (read-string "+1.e1")))
+  (is (instance? Double (read-string "+1e1")))
+
+  (is (instance? Double (read-string "+1.0e-1")))
+  (is (instance? Double (read-string "+1.e-1")))
+  (is (instance? Double (read-string "+1e-1")))
+
+  (is (instance? Double (read-string "1.0e+1")))
+  (is (instance? Double (read-string "1.e+1")))
+  (is (instance? Double (read-string "1e+1")))
+
+  (is (instance? Double (read-string "1.0e-1")))
+  (is (instance? Double (read-string "1.e-1")))
+  (is (instance? Double (read-string "1e-1")))
+
+  (is (instance? Double (read-string "-1.0e+1")))
+  (is (instance? Double (read-string "-1.e+1")))
+  (is (instance? Double (read-string "-1e+1")))
+
+  (is (instance? Double (read-string "-1.0e1")))
+  (is (instance? Double (read-string "-1.e1")))
+  (is (instance? Double (read-string "-1e1")))
+
+  (is (instance? Double (read-string "-1.0e-1")))
+  (is (instance? Double (read-string "-1.e-1")))
+  (is (instance? Double (read-string "-1e-1")))
+
+  (is (instance? Double (read-string "+1.0")))
+  (is (instance? Double (read-string "+1.")))
+
+  (is (instance? Double (read-string "1.0")))
+  (is (instance? Double (read-string "1.")))
+
+  (is (instance? Double (read-string "+0.0")))
+  (is (instance? Double (read-string "+0.")))
+
+  (is (instance? Double (read-string "0.0")))
+  (is (instance? Double (read-string "0.")))
+
+  (is (instance? Double (read-string "-0.0")))
+  (is (instance? Double (read-string "-0.")))
+
+  (is (instance? Double (read-string "-1.0")))
+  (is (instance? Double (read-string "-1.")))
+
+  (is (instance? BigDecimal (read-string "9223372036854775808M")))
+  (is (instance? BigDecimal (read-string "-9223372036854775809M")))
+  (is (instance? BigDecimal (read-string "2147483647M")))
+  (is (instance? BigDecimal (read-string "+1M")))
+  (is (instance? BigDecimal (read-string "1M")))
+  (is (instance? BigDecimal (read-string "+0M")))
+  (is (instance? BigDecimal (read-string "0M")))
+  (is (instance? BigDecimal (read-string "-0M")))
+  (is (instance? BigDecimal (read-string "-1M")))
+  (is (instance? BigDecimal (read-string "-2147483648M")))
+
+  (is (instance? BigDecimal (read-string "+1.0e+1M")))
+  (is (instance? BigDecimal (read-string "+1.e+1M")))
+  (is (instance? BigDecimal (read-string "+1e+1M")))
+
+  (is (instance? BigDecimal (read-string "+1.0e1M")))
+  (is (instance? BigDecimal (read-string "+1.e1M")))
+  (is (instance? BigDecimal (read-string "+1e1M")))
+
+  (is (instance? BigDecimal (read-string "+1.0e-1M")))
+  (is (instance? BigDecimal (read-string "+1.e-1M")))
+  (is (instance? BigDecimal (read-string "+1e-1M")))
+
+  (is (instance? BigDecimal (read-string "1.0e+1M")))
+  (is (instance? BigDecimal (read-string "1.e+1M")))
+  (is (instance? BigDecimal (read-string "1e+1M")))
+
+  (is (instance? BigDecimal (read-string "1.0e1M")))
+  (is (instance? BigDecimal (read-string "1.e1M")))
+  (is (instance? BigDecimal (read-string "1e1M")))
+
+  (is (instance? BigDecimal (read-string "1.0e-1M")))
+  (is (instance? BigDecimal (read-string "1.e-1M")))
+  (is (instance? BigDecimal (read-string "1e-1M")))
+
+  (is (instance? BigDecimal (read-string "-1.0e+1M")))
+  (is (instance? BigDecimal (read-string "-1.e+1M")))
+  (is (instance? BigDecimal (read-string "-1e+1M")))
+
+  (is (instance? BigDecimal (read-string "-1.0e1M")))
+  (is (instance? BigDecimal (read-string "-1.e1M")))
+  (is (instance? BigDecimal (read-string "-1e1M")))
+
+  (is (instance? BigDecimal (read-string "-1.0e-1M")))
+  (is (instance? BigDecimal (read-string "-1.e-1M")))
+  (is (instance? BigDecimal (read-string "-1e-1M")))
+
+  (is (instance? BigDecimal (read-string "+1.0M")))
+  (is (instance? BigDecimal (read-string "+1.M")))
+
+  (is (instance? BigDecimal (read-string "1.0M")))
+  (is (instance? BigDecimal (read-string "1.M")))
+
+  (is (instance? BigDecimal (read-string "+0.0M")))
+  (is (instance? BigDecimal (read-string "+0.M")))
+
+  (is (instance? BigDecimal (read-string "0.0M")))
+  (is (instance? BigDecimal (read-string "0.M")))
+
+  (is (instance? BigDecimal (read-string "-0.0M")))
+  (is (instance? BigDecimal (read-string "-0.M")))
+
+  (is (instance? BigDecimal (read-string "-1.0M")))
+  (is (instance? BigDecimal (read-string "-1.M"))))
 
 (deftest read-ratio
   (is (== 4/2 (read-string "4/2")))

(ns clojure.tools.reader-test
  (:refer-clojure :exclude [read-string])
  (:require [clojure.tools.reader :refer [read-string]]
            [clojure.test :refer [deftest is]]))

(deftest read-integer
  (is (== 42 (read-string "42")))


(deftest read-eval
  (is (= 3 (read-string "#=(+ 1 2)"))))

(deftest read-tagged
  (is (= #inst "2010-11-12T13:14:15.666"
         (read-string "#inst \"2010-11-12T13:14:15.666\"")))
  (is (= #inst "2010-11-12T13:14:15.666"
         (read-string "#inst\"2010-11-12T13:14:15.666\"")))
  (is (= #uuid "550e8400-e29b-41d4-a716-446655440000"
         (read-string "#uuid \"550e8400-e29b-41d4-a716-446655440000\"")))
  (is (= #uuid "550e8400-e29b-41d4-a716-446655440000"
         (read-string "#uuid\"550e8400-e29b-41d4-a716-446655440000\"")))
  (when default-data-reader-fn
    (let [my-unknown (fn [tag val] {:unknown-tag tag :value val})]
      (is (= {:unknown-tag 'foo :value 'bar}
             (with-bindings {default-data-reader-fn my-unknown}
               (read-string "#foo bar")))))))

(defrecord foo [])
(defrecord bar [baz buz])

(deftest read-record
  (is (= (foo.) (read-string "#clojure.tools.reader_test.foo[]")))
  (is (= (foo.) (read-string "#clojure.tools.reader_test.foo []"))) ;; not valid in clojure
  (is (= (foo.) (read-string "#clojure.tools.reader_test.foo{}")))
  (is (= (assoc (foo.) :foo 'bar) (read-string "#clojure.tools.reader_test.foo{:foo bar}")))

  (is (= (map->bar {}) (read-string "#clojure.tools.reader_test.bar{}")))
  (is (= (bar. 1 nil) (read-string "#clojure.tools.reader_test.bar{:baz 1}")))
  (is (= (bar. 1 nil) (read-string "#clojure.tools.reader_test.bar[1 nil]")))
  (is (= (bar. 1 2) (read-string "#clojure.tools.reader_test.bar[1 2]"))))
