Midje icon indicating copy to clipboard operation
Midje copied to clipboard

against-background around :contents forms are evaluated even when filtered out

Open sbgreene1307 opened this issue 7 years ago • 2 comments

The functions in against-background around :contents are evaluated even when you filter out the tests when autotesting.

(fact-group :integration
                    (against-background
                         [(around :contents 
                              (let [] (println "Loading content wrapping functions.") ?form))]))

(midje.repl/autotest :filter (complement :integration))

The println will evaluate.

sbgreene1307 avatar Nov 11 '17 22:11 sbgreene1307

I just took a dive into how against-background and the other background-changers work. They are pretty complicated and their syntax is a bit loose, in the sense that you have a few options as to how to use them, like you can do:

(fact
  (against-background [(f 1) => 2])
  (f 1) => 2)

or

(against-background [(f 1) => 2]
  (fact (f 1) => 2))

to similar effect.

Strangely, the second form doesn't run into the bug you've described, so I would recommend using that form for now.

You can also toy around using :facts or :checks instead of :contents as the first argument for around. They have different behavior, but also don't seem to encounter the bug.

Sorry that this is confusing, there are a few things surrounding background-changers that could be clearer, but making them so isn't easy given their current expressive power/complexity.

Fun note if anyone knows the answer, the following causes a stack overflow:

(macroexpand
  `(fact (against-background [(around :contents (do ?form (println "__")))]) 
     1 => 2))

while this works fine:

(macroexpand
  `(fact (against-background [(around :facts (do ?form (println "__")))]) 
     1 => 2))

philomates avatar Nov 13 '17 17:11 philomates

I want to apologize for the against-background form. I didn't spend enough "hammock time" on it, and the implementation suffered from being written by a novice Clojure person. Someone should think of a better abstraction.

That said, around :contents is particularly horrible. The other forms essentially attach before-and-after functions to whatever is within their lexical scope. (So you can do setup for many facts within the around form.) :contents just behaves differently, because it's not applied to recognizable sub-forms (fact...) but rather takes effect at the moment the Clojure interpreter sees it.

marick avatar Nov 14 '17 00:11 marick