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

When using canister in tests, I want to save & restore the original proc #8

Open
aelkiss opened this issue Oct 20, 2023 · 2 comments
Open

Comments

@aelkiss
Copy link
Member

aelkiss commented Oct 20, 2023

It would be nice for canister to have the ability to reload/restore the original state. Frequently in tests I want to do something like:

around(:each) do |example|
  oldthing = Services[:thing]
  Services.register(:thing) { newthing }
  example.run
  Services.register(:thing) { oldthing }
end

This essentially results in oldthing being reified; even if later on the cache for :thing would have been invalidated when updating some key it was originally dependent on, it won't after running this test. Having some support for this would be nice, as well as potentially a test helper for rspec like this (but that could save & restore the original proc)

def override_service(key, &block)
  around(:each) do |example|
    old_val = Services[key]
    Services.register(key, &block)
    example.run
    Services.register(key) { old_val }
  end
end

(this would need to be generic as to the name of Services; I don't think this could be a method on the canister object itself though since it would need to be able to call around...?)

Similarly, if there are other issues with respect to cached values of services, test ordering can have strange results; it would be nice (even when not injecting some other dependency into a test) to have the ability to reset canister to its original state.

@billdueber
Copy link

I theory, Cannister itself could do something like this if it could just push its procs and cached values onto a stack in a faux-CPS-style, couldn't it? Maybe something like

around(:each) do |example|
  Services.override do |s| # copy the procs and cached values and push onto the top of the stack
    s.register(:key) { val }
    s.register(:other_key) { other_val }
    example.run
  end # pop the stack 
end

I haven't looked into the guts of Canister enough to know how hard this would be. And then there's thread safety...

@billdueber
Copy link

Took a (non-threadsafe) shot at this in #9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants