From a12913b6cfbc9ae4edeed826fa557965ea028eeb Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 23 Mar 2018 16:29:17 +1100 Subject: [PATCH] Add url coercer --- README.md | 5 +++-- lib/envied/coercer.rb | 2 +- lib/envied/coercer/envied_string.rb | 5 +++++ spec/coercer_spec.rb | 30 +++++++++++++++++++++++++++-- spec/envied_spec.rb | 3 ++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 38a2b96..157d541 100644 --- a/README.md +++ b/README.md @@ -92,10 +92,11 @@ The following types are supported: * `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`) * `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`) * `:uri` (e.g. 'http://www.google.com' becomes `URI.parse('http://www.google.com')` +* `:uri_with_scheme` (is like :uri, but will raise an exception `if URI.parse('www.google.com').scheme.nil?`) ### Groups -Groups give you more flexibility to define when variables are needed. +Groups give you more flexibility to define when variables are needed. It's similar to groups in a Gemfile: ```ruby @@ -147,7 +148,7 @@ variable :FORCE_SSL, :boolean, default: 'false' variable :PORT, :integer, default: proc {|envied| envied.FORCE_SSL ? 443 : 80 } ``` -Please remember that ENVied only **reads** from ENV; it doesn't mutate ENV. +Please remember that ENVied only **reads** from ENV; it doesn't mutate ENV. Don't let setting a default for, say `RAILS_ENV`, give you the impression that `ENV['RAILS_ENV']` is set. As a rule of thumb you should only use defaults: * for local development diff --git a/lib/envied/coercer.rb b/lib/envied/coercer.rb index 428ab5e..eb8ce48 100644 --- a/lib/envied/coercer.rb +++ b/lib/envied/coercer.rb @@ -26,7 +26,7 @@ def coerce_method_for(type) def self.supported_types @supported_types ||= begin - [:hash, :array, :time, :date, :symbol, :boolean, :integer, :string, :uri, :float].sort + [:hash, :array, :time, :date, :symbol, :boolean, :integer, :string, :uri, :uri_with_scheme, :float].sort end end diff --git a/lib/envied/coercer/envied_string.rb b/lib/envied/coercer/envied_string.rb index 8cd4681..124b2a4 100644 --- a/lib/envied/coercer/envied_string.rb +++ b/lib/envied/coercer/envied_string.rb @@ -15,6 +15,11 @@ def to_uri(str) ::URI.parse(str) end + def to_uri_with_scheme(str) + result = to_uri(str) + result.scheme.nil? ? raise_unsupported_coercion(str, __method__) : result + end + def to_integer(str) Integer(str) rescue ArgumentError diff --git a/spec/coercer_spec.rb b/spec/coercer_spec.rb index 3387401..d4c846b 100644 --- a/spec/coercer_spec.rb +++ b/spec/coercer_spec.rb @@ -114,8 +114,34 @@ def coerce_to(type) describe 'to uri' do let(:coerce){ coerce_to(:uri) } - it 'converts strings to uris' do - expect(coerce['http://www.google.com']).to be_a(URI) + it 'converts strings to generic uris' do + expect(coerce['server.example.com']).to be_a(URI::Generic) + end + + it 'converts strings to ftp uris' do + expect(coerce['ftp://ftp.example.com']).to be_a(URI::FTP) + end + end + + describe 'to uri_with_scheme' do + let(:coerce){ coerce_to(:uri_with_scheme) } + + it 'converts strings to http uris' do + expect(coerce['http://www.google.com'].scheme).to eql 'http' + end + + it 'converts strings to https uris' do + expect(coerce['https://github.com'].scheme).to eql 'https' + end + + it 'converts strings to redis uris' do + expect(coerce['redis://example.com:6379'].scheme).to eql 'redis' + end + + it 'fails for non uris' do + expect { + coerce['server.example.com'] + }.to raise_error(Coercible::UnsupportedCoercion) end end end diff --git a/spec/envied_spec.rb b/spec/envied_spec.rb index 06ba2f5..f968212 100644 --- a/spec/envied_spec.rb +++ b/spec/envied_spec.rb @@ -365,13 +365,14 @@ def envied_require(*args) describe 'URIable' do before do configure do - variable :site_url, :uri + variable :site_url, :uri_with_scheme end.and_ENV('site_url' => 'https://www.google.com') envied_require end it 'yields a URI from string' do expect(ENVied.site_url).to be_a URI + expect(ENVied.site_url.scheme).to eq 'https' expect(ENVied.site_url.host).to eq 'www.google.com' end end