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
or
alternatives. Conformingnil
using 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: