summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2017-07-23 16:12:53 -0500
committerSamuel Giddins <segiddins@segiddins.me>2017-07-23 16:12:53 -0500
commit7507c52e6bbc292ff3fddca0d7b070295a5074c4 (patch)
treec11f57de4326564f2b46bc50af4402f9b7e11917
parent83fbd476bcdc6e3720e10f91862a65ca8b981ce6 (diff)
downloadbundler-7507c52e6bbc292ff3fddca0d7b070295a5074c4.tar.gz
Add unit tests for the settings validator
-rw-r--r--lib/bundler/settings.rb4
-rw-r--r--lib/bundler/settings/validator.rb8
-rw-r--r--spec/bundler/settings/validator_spec.rb111
3 files changed, 117 insertions, 6 deletions
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index ffdac1f979..1993717fc9 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -277,14 +277,14 @@ module Bundler
end
end
- private
-
def key_for(key)
key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
key = key.to_s.gsub(".", "__").upcase
"BUNDLE_#{key}"
end
+ private
+
def parent_setting_for(name)
split_specific_setting_for(name)[0]
end
diff --git a/lib/bundler/settings/validator.rb b/lib/bundler/settings/validator.rb
index cacb9f91da..eae9d4d575 100644
--- a/lib/bundler/settings/validator.rb
+++ b/lib/bundler/settings/validator.rb
@@ -12,7 +12,7 @@ module Bundler
@validate = validate
end
- def validate(key, value, settings)
+ def validate!(key, value, settings)
instance_exec(key, value, settings, &@validate)
end
@@ -34,7 +34,7 @@ module Bundler
end
def k(key)
- Bundler.settings.send(:key_for, key)
+ Bundler.settings.key_for(key)
end
end
@@ -49,9 +49,9 @@ module Bundler
end
private_class_method :rule
- def self.validate(key, value, settings)
+ def self.validate!(key, value, settings)
rules_to_validate = rules[key]
- rules_to_validate.each {|rule| rule.validate(key, value, settings) }
+ rules_to_validate.each {|rule| rule.validate!(key, value, settings) }
end
rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings|
diff --git a/spec/bundler/settings/validator_spec.rb b/spec/bundler/settings/validator_spec.rb
new file mode 100644
index 0000000000..e4ffd89435
--- /dev/null
+++ b/spec/bundler/settings/validator_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+RSpec.describe Bundler::Settings::Validator do
+ describe ".validate!" do
+ def validate!(key, value, settings)
+ transformed_key = Bundler.settings.key_for(key)
+ if value.nil?
+ settings.delete(transformed_key)
+ else
+ settings[transformed_key] = value
+ end
+ described_class.validate!(key, value, settings)
+ settings
+ end
+
+ it "path and path.system are mutually exclusive" do
+ expect(validate!("path", "bundle", {})).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", "bundle", "BUNDLE_PATH__SYSTEM" => false)).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", "bundle", "BUNDLE_PATH__SYSTEM" => true)).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path", nil, "BUNDLE_PATH__SYSTEM" => true)).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path", nil, "BUNDLE_PATH__SYSTEM" => false)).to eq("BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path", nil, {})).to eq({})
+
+ expect(validate!("path.system", true, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path.system", false, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH" => "bundle", "BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path.system", nil, "BUNDLE_PATH" => "bundle")).to eq("BUNDLE_PATH" => "bundle")
+ expect(validate!("path.system", true, {})).to eq("BUNDLE_PATH__SYSTEM" => true)
+ expect(validate!("path.system", false, {})).to eq("BUNDLE_PATH__SYSTEM" => false)
+ expect(validate!("path.system", nil, {})).to eq({})
+ end
+
+ it "a group cannot be in both `with` & `without` simultaneously" do
+ expect do
+ validate!("with", "", {})
+ validate!("with", nil, {})
+ validate!("with", "", "BUNDLE_WITHOUT" => "a")
+ validate!("with", nil, "BUNDLE_WITHOUT" => "a")
+ validate!("with", "b:c", "BUNDLE_WITHOUT" => "a")
+
+ validate!("without", "", {})
+ validate!("without", nil, {})
+ validate!("without", "", "BUNDLE_WITH" => "a")
+ validate!("without", nil, "BUNDLE_WITH" => "a")
+ validate!("without", "b:c", "BUNDLE_WITH" => "a")
+ end.not_to raise_error
+
+ expect { validate!("with", "b:c", "BUNDLE_WITHOUT" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `with` to "b:c" failed:
+ - a group cannot be in both `with` & `without` simultaneously
+ - `without` is current set to [:c, :d]
+ - the `c` groups conflict
+ EOS
+
+ expect { validate!("without", "b:c", "BUNDLE_WITH" => "c:d") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `without` to "b:c" failed:
+ - a group cannot be in both `with` & `without` simultaneously
+ - `with` is current set to [:c, :d]
+ - the `c` groups conflict
+ EOS
+ end
+ end
+
+ describe described_class::Rule do
+ let(:keys) { %w[key] }
+ let(:description) { "rule description" }
+ let(:validate) { proc { raise "validate called!" } }
+ subject(:rule) { described_class.new(keys, description, &validate) }
+
+ describe "#validate!" do
+ it "calls the block" do
+ expect { rule.validate!("key", nil, {}) }.to raise_error(RuntimeError, /validate called!/)
+ end
+ end
+
+ describe "#fail!" do
+ it "raises with a helpful message" do
+ expect { subject.fail!("key", "value", "reason1", "reason2") }.to raise_error Bundler::InvalidOption, strip_whitespace(<<-EOS).strip
+ Setting `key` to "value" failed:
+ - rule description
+ - reason1
+ - reason2
+ EOS
+ end
+ end
+
+ describe "#set" do
+ it "works when the value has not changed" do
+ allow(Bundler.ui).to receive(:info).never
+
+ subject.set({}, "key", nil)
+ subject.set({ "BUNDLE_KEY" => "value" }, "key", "value")
+ end
+
+ it "prints out when the value is changing" do
+ settings = {}
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to \"value\", since rule description, reason1")
+ subject.set(settings, "key", "value", "reason1")
+ expect(settings).to eq("BUNDLE_KEY" => "value")
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to \"value2\", since rule description, reason2")
+ subject.set(settings, "key", "value2", "reason2")
+ expect(settings).to eq("BUNDLE_KEY" => "value2")
+
+ expect(Bundler.ui).to receive(:info).with("Setting `key` to nil, since rule description, reason3")
+ subject.set(settings, "key", nil, "reason3")
+ expect(settings).to eq({})
+ end
+ end
+ end
+end