First I’d like to air an assumption I got by osmosis:
Code can rely on settings to exist and have a sensible default.
:foo: :bar: true, code can do
if Settings.foo.barwithout worrying that foo or bar can be entirely missing (which would return nil or blow up respectively).
When naming, we care about how it reads, e.g.
if do_itis better than the double negative
unless skip_it. We don’t care which value is “typical” or backward-compatible.
Implications for tests
To what degree tests can/should rely on
settings.yml vs providing their own settings?
stub_settings vs stub_settings_merge
stub_settings replaces the top-level
Settings completely with what you provide. You can’t possibly provide everything, so most settings will be missing. Code that doesn’t expect this can misbehave in unexpected ways, so AFAICT it’s never safe to use (except in tests of Settings machinery itself).
stub_settings_merge deep-merges what you provide on top of settings.yml, and is what you want in tests.
[This is prompted by #14662 discussion.
The code under test nicely takes a portion of settings as an argument, allowing injecting OpenStruct or similar in tests . @enoodle caught me injecting the actual live
Again, I’m worried that if I write tests injecting options
:bar and later a
:baz setting appears, in some cases
nil may silently do silly things (like exit early), and test might pass despite no longer testing any actual behavior.
=> The solution I came up with is injecting a
Struct instead of
This way if code started accessing
options.baz the test would blow up, and we’ll remember to add the option in test.
What do you think?