emacs-buttercup icon indicating copy to clipboard operation
emacs-buttercup copied to clipboard

WIP: Add support for capturing dynamic binding environment

Open Fuco1 opened this issue 5 years ago • 10 comments

Fixes #127, kind of.

This is quite a bit of black magic and I'm using eval, however I can't really find any other way.

Without using :env it falls back to the old code so this should not affect any current usage.

A simple test case

(describe "env test"
  :env ((kill-ring kill-ring))

  (it "should capture environment"
    (with-temp-buffer
      (insert "asdasd")
      (goto-char (point-min))
      (kill-line))
    (expect kill-ring :to-equal (list "asdasd")))

  (it "should restore environment"
    (expect kill-ring :to-be nil)))

without the :env flag the second test fails as it is polluted by the first one doing the killing.

Fuco1 avatar Jul 23 '18 15:07 Fuco1

Thank you for the PR. Wouldn't it be easier and more readable to just setq the variable in before-each, or maybe just support an around-each type of thing?

jorgenschaefer avatar Jul 27 '18 11:07 jorgenschaefer

@jorgenschaefer Problem with setq is that it corrupts the global state. It would not be a problem if buttercup run each test case in a separate Emacs instance but that would be crazy slow.

It might work for one describe set if I always initialize it but basically it would force me to do it absolutely everywhere in the entire test suite. For example, imagine I set case-fold-search to nil in one suite, then for the rest of the execution it is going to have this value.

What can be done with the around-each would be to get the value and then re-set it which would work but we must take care of errors also (i.e. never forget to re-set the value). The user would have to do this manually for every variable then. This is basically what this PR does.

Theoretically, this might work

(describe "Backup"
  :var (kill-ring-backup)

  (before-each
    (setq kill-ring-backup kill-ring)
    (setq kill-ring ("foobar")))

  (after-each
    (setq kill-ring kill-ring-backup))

  (it "kill ring should not be empty"
    (expect (< 0 (length kill-ring)) :to-be-truthy)))

Then the question is what are the guarantees on after-each.

Fuco1 avatar Jul 27 '18 12:07 Fuco1

What you described is a common idiom in javascript but remember that there the scoping works different

describe('getProductValue', () => {

    let edsnDown

    describe('when edsn is up', () => {

        beforeEach(() => {
            edsnDown = false
        })

        it("should return '1' when we have elk only", () => {
            expect(getProductValue(true, edsnDown)).toEqual('1')
        })

        it("should return '2' when we have elk and gas", () => {
            expect(getProductValue(false, edsnDown)).toEqual('2')
        })

    })

})

here the edsnDown will never spill outside of the describe... in Emacs special variables will :(

Fuco1 avatar Jul 27 '18 12:07 Fuco1

How about around?

(describe "Backup"
  (around-each block
    (let ((kill-ring '("foobar")))
      (funcall block)))

  (it "kill ring should not be empty"
    (expect (< 0 (length kill-ring)) :to-be-truthy)))

jorgenschaefer avatar Aug 03 '18 10:08 jorgenschaefer

@jorgenschaefer That is actually really cool idea. You were doing some ruby lately heh? :D

Yea I think that could work if implemented properly. I'll try to take a look on that if you don't mind (or have it already implemented)

Fuco1 avatar Aug 03 '18 11:08 Fuco1

Am I getting a Ruby dialect? Help! :-D I have nothing implemented and I would love such a feature, thank you!

jorgenschaefer avatar Aug 03 '18 11:08 jorgenschaefer

@Fuco1 Great work so far with this! Looking forward to its completion!

P.S. As a Rubyist myself I welcome any suggestion to get buttercup closer to what RSpec offers - it's a pretty amazing framework.

bbatsov avatar Sep 16 '18 05:09 bbatsov

Is there any progress on this? This is quite an important feature missing in buttercup. Without it, "mocking" special variables becomes quite annoying.

wyuenho avatar Aug 10 '22 13:08 wyuenho

I probably won't work on this in any reasonably close future.

Fuco1 avatar Aug 10 '22 16:08 Fuco1

This PR is probably older than my maintainership, and as it was marked WIP I never gave it much thought. I don't think I'll get to it soon considering how little time I have to spend on this project.
If you have any specific problem, please file a separate issue. Maybe we can figure something out.

snogge avatar Aug 10 '22 21:08 snogge