Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow more clojure.core functions to be faked #64

Closed
marick opened this issue Nov 9, 2011 · 6 comments
Closed

Allow more clojure.core functions to be faked #64

marick opened this issue Nov 9, 2011 · 6 comments
Labels
Milestone

Comments

@marick
Copy link
Owner

marick commented Nov 9, 2011

Currently, you can't do this:

(fact (f ..x..) => 1 (provided (every? odd? ..x..))

Because every? is used in the Midje code that processes prerequisites.

As of Midje 1.0.3-alpha5, you'll get a helpful failure message, but it'd be better if it didn't fail. Possibility:

Isolate a narrow core of Midje functions that can cause this kind of you-tried-to-use-a-faked-function-to-see-if-it-was-a-faked-function problem, and use guaranteed-unfaked alternates within that core. That is:

(def safe-every? clojure.core/every?)

; ... midje code ...
... (safe-every? ....)

@denlab
Copy link

denlab commented Dec 14, 2011

vote +1

Also having the forbidden functions documented would be great

@marick
Copy link
Owner Author

marick commented Dec 15, 2011

As far as I can tell, you can only tell what functions are forbidden at runtime.

On Dec 13, 2011, at 11:50 PM, denlab wrote:

vote +1

Also having the forbidden functions documented would be great


Reply to this email directly or view it on GitHub:
#64 (comment)


Brian Marick, Artisanal Labrador
Now working at http://path11.com
Contract programming in Ruby and Clojure
Occasional consulting on Agile

@AlexBaranosky
Copy link
Collaborator

@marick could this be tested by writing code to generate one fact for every function in clojure.core?

(doseq [[x _] (remove (comp :macro meta second) (ns-publics 'clojure.core))] ;; all non-macro vars
  (fact 
    (x) => anything
    (provided (x) => nil)))

Then write down all of the ones that fail, and create copies of them to be used internally by Midje?

Or did I misunderstand this... Since I am pretty tired right now.

@AlexBaranosky
Copy link
Collaborator

This is what I'm using to check:

(defn test-em []
  (macro-for [[x _] (remove (comp :macro meta second) (ns-publics 'clojure.core))] ;; all non-macro vars
    `(fact
       (~x) => anything
       (~'provided (~x) => nil))))

(eval (test-em))

It might have been just my misunderstanding, but this technique won't be able to solve the issue for all of these, but it will be able to narrow the damage radius.

I'll try to compile two list:

One) of all functions used in Midje that cause this issue
Two) of functions that are used by functions Midje uses (which we can't fix, as far as I understand it)

@AlexBaranosky
Copy link
Collaborator

This is a pain in the ...expletive...

The plan was to go through these an add to #'used-by-midje as I identified them, but as you can see I didn't get that far :)

Here is the code I was messing with for future reference, if anyone wants to try this. For now I give up.

(def used-by-midje #{}))

(def inlined #{
               #'clojure.core/*
               #'clojure.core/*'
               #'clojure.core/+
               #'clojure.core/+'
               #'clojure.core/-
               #'clojure.core/-'
               #'clojure.core/<
               #'clojure.core/<=
               #'clojure.core/=
               #'clojure.core/==
               #'clojure.core/>
               #'clojure.core/>=
               #'clojure.core/aclone
               #'clojure.core/aget
               #'clojure.core/alength
               #'clojure.core/aset
               #'clojure.core/bit-and
               #'clojure.core/bit-and-not
               #'clojure.core/bit-not
               #'clojure.core/bit-or
               #'clojure.core/bit-shift-left
               #'clojure.core/bit-shift-right
               #'clojure.core/bit-xor
               #'clojure.core/boolean
               #'clojure.core/boolean-array
               #'clojure.core/booleans
               #'clojure.core/byte
               #'clojure.core/byte-array
               #'clojure.core/bytes
               #'clojure.core/char
               #'clojure.core/char-array
               #'clojure.core/chars
               #'clojure.core/compare
               #'clojure.core/count
               #'clojure.core/dec
               #'clojure.core/dec'
               #'clojure.core/double
               #'clojure.core/double-array
               #'clojure.core/doubles
               #'clojure.core/float
               #'clojure.core/float-array
               #'clojure.core/floats
               #'clojure.core/get
               #'clojure.core/identical?
               #'clojure.core/inc
               #'clojure.core/inc'
               #'clojure.core/int
               #'clojure.core/int-array
               #'clojure.core/ints
               #'clojure.core/long
               #'clojure.core/long-array
               #'clojure.core/longs
               #'clojure.core/max
               #'clojure.core/min
               #'clojure.core/neg?
               #'clojure.core/nil?
               #'clojure.core/nth
               #'clojure.core/num
               #'clojure.core/object-array
               #'clojure.core/pos?
               #'clojure.core/quot
               #'clojure.core/rem
               #'clojure.core/short
               #'clojure.core/short-array
               #'clojure.core/shorts
               #'clojure.core/unchecked-add
               #'clojure.core/unchecked-add-int
               #'clojure.core/unchecked-byte
               #'clojure.core/unchecked-char
               #'clojure.core/unchecked-dec
               #'clojure.core/unchecked-dec-int
               #'clojure.core/unchecked-divide-int
               #'clojure.core/unchecked-double
               #'clojure.core/unchecked-float
               #'clojure.core/unchecked-inc
               #'clojure.core/unchecked-inc-int
               #'clojure.core/unchecked-int
               #'clojure.core/unchecked-long
               #'clojure.core/unchecked-multiply
               #'clojure.core/unchecked-multiply-int
               #'clojure.core/unchecked-negate
               #'clojure.core/unchecked-negate-int
               #'clojure.core/unchecked-remainder-int
               #'clojure.core/unchecked-short
               #'clojure.core/unchecked-subtract
               #'clojure.core/unchecked-subtract-int
               #'clojure.core/zero?
               })

(def macros #{
              #'clojure.core/->
              #'clojure.core/->>
              #'clojure.core/..
              #'clojure.core/amap
              #'clojure.core/and
              #'clojure.core/areduce
              #'clojure.core/assert
              #'clojure.core/binding
              #'clojure.core/bound-fn
              #'clojure.core/case
              #'clojure.core/comment
              #'clojure.core/cond
              #'clojure.core/condp
              #'clojure.core/declare
              #'clojure.core/definline
              #'clojure.core/definterface
              #'clojure.core/defmacro
              #'clojure.core/defmethod
              #'clojure.core/defmulti
              #'clojure.core/defn
              #'clojure.core/defn-
              #'clojure.core/defonce
              #'clojure.core/defprotocol
              #'clojure.core/defrecord
              #'clojure.core/defstruct
              #'clojure.core/deftype
              #'clojure.core/delay
              #'clojure.core/doseq
              #'clojure.core/dosync
              #'clojure.core/dotimes
              #'clojure.core/doto
              #'clojure.core/extend-protocol
              #'clojure.core/extend-type
              #'clojure.core/fn
              #'clojure.core/for
              #'clojure.core/future
              #'clojure.core/gen-class
              #'clojure.core/gen-interface
              #'clojure.core/if-let
              #'clojure.core/if-not
              #'clojure.core/import
              #'clojure.core/io!
              #'clojure.core/lazy-cat
              #'clojure.core/lazy-seq
              #'clojure.core/let
              #'clojure.core/letfn
              #'clojure.core/locking
              #'clojure.core/loop
              #'clojure.core/memfn
              #'clojure.core/ns
              #'clojure.core/or
              #'clojure.core/proxy
              #'clojure.core/proxy-super
              #'clojure.core/pvalues
              #'clojure.core/refer-clojure
              #'clojure.core/reify
              #'clojure.core/sync
              #'clojure.core/time
              #'clojure.core/when
              #'clojure.core/when-first
              #'clojure.core/when-let
              #'clojure.core/when-not
              #'clojure.core/while
              #'clojure.core/with-bindings
              #'clojure.core/with-in-str
              #'clojure.core/with-loading-context
              #'clojure.core/with-local-vars
              #'clojure.core/with-open
              #'clojure.core/with-out-str
              #'clojure.core/with-precision
              #'clojure.core/with-redefs
              })

;; Midje doesn't use directly, yet still Midje won't allow you to fake
(def secondarily-used-by-midje #{#'clojure.core/chunk-buffer
                                 #'clojure.core/chunked-seq?
                                 #'clojure.core/list*})

(def bad-fns (union inlined macros used-by-midje secondarily-used-by-midje))

(defn test-em []
  (macro-for [x (for [[s v] (sort (ns-publics 'clojure.core))
                          :when (and (not (#{:inline :macro} (meta v)))
                                     (not (bad-fns v))
                                     (#{\a \b \c \d \e \f \g \h \i \j \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z} (first (name s))))
                          ]
                         s)]
    `(fact (str ~x)
       (~x) => anything
       (~'provided (~x) => nil))))

(eval (test-em))

@marick
Copy link
Owner Author

marick commented May 7, 2013

I've decided that allowing mocking of clojure core functions isn't a dramatically useful feature.

@marick marick closed this as completed May 7, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants