I found a way to throw NullPointerExceptions by generating values using an s/or spec. I want to be able to generate and label a nil value, no s/nilable isn't suitable.
Is this a bug in clojure.spec?
(ns blah
(:require [clojure.spec.alpha :as s]))
(s/def ::fine (s/or :int int? :nil nil?)
(s/def ::throws (s/or :int (s/int-in 1 5) :zero zero? :nil nil?)
(s/exercise ::fine)
=>
([nil [:nil nil]
[-1 [:int -1]]
[nil [:nil nil]]
[0 [:int 0]]
[nil [:nil nil]]
[15 [:int 15]]
[-25 [:int -25]]
[nil [:nil nil]]
[-2 [:int -2]]
[-30 [:int -30]]])]])
(s/exercise ::throws)
=>
NullPointerException clojure.lang.Numbers.ops (Numbers.java:1018)
If you limit the number of times ::throws is exercised, you see correct :int and :zero values, it's the :nil which throws.
This works:
I assume spec will try to conform in order of the
oralternatives. Conformingnilusing thezero?predicate will crash, but movingnil?in front of that, will prevent that from happening.What also works is using a set instead of a predicate: