Last active
March 9, 2024 10:49
-
-
Save mrk21/3c6f29aa91659dcaf45eefba11f866a3 to your computer and use it in GitHub Desktop.
Define a method liked `ENV.fetch()` which returns specified default value even when a value of specified key was empty string. see: https://mrk21.hatenablog.com/entry/2024/03/09/190844
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class << ENV | |
# This method behavior is almost same as `ENV.fetch()`, but it returns default value even when the value was empty string. | |
def fetch2(*args, &block) | |
key, default = args | |
value = fetch(*args, &block) | |
return value if value != '' | |
raise KeyError, format('key not found: "%s"', key) if args.size == 1 && !block | |
warn('block supersedes default value argument', uplevel: 1) if args.size == 2 && block | |
block ? yield(key) : default | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative './env' | |
RSpec.describe ENV do | |
before do | |
described_class['__DUMMY_FOR_TEST1'] = '1' | |
described_class['__DUMMY_FOR_TEST3'] = '' | |
end | |
after do | |
described_class.delete('__DUMMY_FOR_TEST1') | |
described_class.delete('__DUMMY_FOR_TEST3') | |
end | |
describe '.fetch2(key, default, &block)' do | |
context 'existed `key`' do | |
let(:key) { '__DUMMY_FOR_TEST1' } | |
context 'did not specify neither `default` nor `block`' do | |
it 'returns value of `key`' do | |
expect(described_class.fetch2(key)).to eq '1' | |
end | |
end | |
context 'specified `default`' do | |
it 'returns value of `key`' do | |
expect(described_class.fetch2(key, '2')).to eq '1' | |
end | |
end | |
context 'specified `block`' do | |
it 'returns value of `key`' do | |
expect(described_class.fetch2(key) { '3' }).to eq '1' | |
described_class.fetch2(key) { |k| expect(k).to eq key } | |
end | |
end | |
context 'specified `default` with `block`' do | |
it 'outputs warn, and it returns value of `key`' do | |
expect do | |
expect(described_class.fetch2(key, '2') { '3' }).to eq '1' | |
end.to output(%r{env.rb:\d+: warning: block supersedes default value argument\n}).to_stderr | |
described_class.fetch2(key, '2') { |k| expect(k).to eq key } | |
end | |
end | |
end | |
context 'did not exist `key`' do | |
let(:key) { '__DUMMY_FOR_TEST2' } | |
context 'did not specify neither `default` nor `block`' do | |
it 'raises exception' do | |
expect { described_class.fetch2(key) }.to raise_error(KeyError, 'key not found: "%s"' % key) | |
end | |
end | |
context 'specified `default`' do | |
it 'returns `default`' do | |
expect(described_class.fetch2(key, '2')).to eq '2' | |
end | |
end | |
context 'specified `block`' do | |
it 'returns return value of `block`' do | |
expect(described_class.fetch2(key) { '3' }).to eq '3' | |
described_class.fetch2(key) { |k| expect(k).to eq key } | |
end | |
end | |
context 'specified `default` with `block`' do | |
it 'outputs warn, and it returns return value of `block`' do | |
expect do | |
expect(described_class.fetch2(key, '2') { '3' }).to eq '3' | |
end.to output(%r{env.rb:\d+: warning: block supersedes default value argument\n}).to_stderr | |
described_class.fetch2(key, '2') { |k| expect(k).to eq key } | |
end | |
end | |
end | |
context 'existed `key`, but the value was empty string' do | |
let(:key) { '__DUMMY_FOR_TEST3' } | |
context 'did not specify neither `default` nor `block`' do | |
it 'raises exception' do | |
expect { described_class.fetch2(key) }.to raise_error(KeyError, 'key not found: "%s"' % key) | |
end | |
end | |
context 'specified `default`' do | |
it 'returns `default`' do | |
expect(described_class.fetch2(key, '2')).to eq '2' | |
end | |
end | |
context 'specified `block`' do | |
it 'returns return value of `block`' do | |
expect(described_class.fetch2(key) { '3' }).to eq '3' | |
described_class.fetch2(key) { |k| expect(k).to eq key } | |
end | |
end | |
context 'specified `default` with `block`' do | |
it 'outputs warn, and it returns return value of `block`' do | |
expect do | |
expect(described_class.fetch2(key, '2') { '3' }).to eq '3' | |
end.to output(%r{env.rb:\d+: warning: block supersedes default value argument\n}).to_stderr | |
described_class.fetch2(key, '2') { |k| expect(k).to eq key } | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment