require "fileutils" require "pathname" require "tmpdir" require "yaml" require "support/fakefs" require "librarian/config/database" describe Librarian::Config::Database do include ::Support::FakeFS def write_yaml!(path, *yamlables) path = Pathname(path) path.dirname.mkpath unless path.dirname.directory? File.open(path, "wb"){|f| yamlables.each{|y| YAML.dump(y, f)}} end let(:adapter_name) { "gem" } let(:env) { { } } let(:pwd) { Pathname(Dir.tmpdir) } let(:home) { Pathname("~").expand_path } let(:project_path) { nil } let(:specfile_name) { nil } let(:global) { home.join(".librarian/gem/config") } let(:local) { pwd.join(".librarian/gem/config") } let(:specfile) { pwd.join("Gemfile") } before do FileUtils.mkpath(pwd) FileUtils.touch(specfile) end let(:database) do described_class.new(adapter_name, :env => env, :pwd => pwd.to_s, :home => home.to_s, :project_path => project_path, :specfile_name => specfile_name ) end context "when a key is given globally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do write_yaml! global, raw_key => value end it "should have the key globally" do expect(database.global[key]).to eq value end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should not have the key locally" do expect(database.local[key]).to be_nil end it "should have the key generally" do expect(database[key]).to eq value end end context "when a key is set globally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do database.global[key] = value end it "should have the key globally" do expect(database.global[key]).to eq value end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should not have the key locally" do expect(database.local[key]).to be_nil end it "should have the key generally" do expect(database[key]).to eq value end it "should persist the key" do data = YAML.load_file(global) expect(data).to eq({raw_key => value}) end end context "when the key is set and unset globally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do database.global[key] = value database.global[key] = nil end it "should not have the key globally" do expect(database.global[key]).to be_nil end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should not have the key locally" do expect(database.local[key]).to be_nil end it "should not have the key generally" do expect(database[key]).to be_nil end it "should unpersist the key" do expect(File).to_not exist global end end context "when a key is given in the env" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } #override let(:env) { {raw_key => value} } it "should not have the key globally" do expect(database.global[key]).to be_nil end it "should have the key in the env" do expect(database.env[key]).to eq value end it "should not have the key locally" do expect(database.local[key]).to be_nil end it "should have the key generally" do expect(database[key]).to eq value end end context "when a key is given locally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do write_yaml! local, raw_key => value end it "should not have the key globally" do expect(database.global[key]).to be_nil end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should have the key locally" do expect(database.local[key]).to eq value end it "should have the key generally" do expect(database[key]).to eq value end end context "when a key is set locally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do database.local[key] = value end it "should not have the key globally" do expect(database.global[key]).to be_nil end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should have the key locally" do expect(database.local[key]).to eq value end it "should have the key generally" do expect(database[key]).to eq value end it "should persist the key" do data = YAML.load_file(local) expect(data).to eq({raw_key => value}) end end context "when the key is set and unset locally" do let(:key) { "jam" } let(:value) { "jelly" } let(:raw_key) { "LIBRARIAN_GEM_JAM" } before do database.local[key] = value database.local[key] = nil end it "should not have the key globally" do expect(database.global[key]).to be_nil end it "should not have the key in the env" do expect(database.env[key]).to be_nil end it "should not have the key locally" do expect(database.local[key]).to be_nil end it "should not have the key generally" do expect(database[key]).to be_nil end it "should unpersist the key" do expect(File).to_not exist local end end context "setting malformatted keys" do it "should ban caps" do expect { database.global["JAM"] = "jelly" }. to raise_error Librarian::Error, %[key not permitted: "JAM"] end it "should ban double dots" do expect { database.global["jam..jam"] = "jelly" }. to raise_error Librarian::Error, %[key not permitted: "jam..jam"] end end context "setting banned keys" do it "should ban the specfile key" do expect { database.global["gemfile"] = "jelly" }. to raise_error Librarian::Error, %[key not permitted: "gemfile"] end it "should ban the global-config key" do expect { database.global["config"] = "jelly" }. to raise_error Librarian::Error, %[key not permitted: "config"] end end context "project_path" do context "by default" do it "should give the default project path" do expect(database.project_path).to eq Pathname("/tmp") end end context "when the specfile is set in the env" do let(:env) { {"LIBRARIAN_GEM_GEMFILE" => "/non/sense/path/to/Sillyfile"} } it "should give the project path from the env-set specfile" do expect(database.project_path).to eq Pathname("/non/sense/path/to") end end end context "specfile_path" do context "by default" do it "should give the default specfile path" do expect(database.specfile_path).to eq specfile end end context "when set in the env" do let(:env) { {"LIBRARIAN_GEM_GEMFILE" => "/non/sense/path/to/Sillyfile"} } it "should give the given specfile path" do expect(database.specfile_path).to eq Pathname("/non/sense/path/to/Sillyfile") end end context "when the project_path is assigned" do let(:project_path) { "/non/sense/path/to" } it "should give the assigned specfile path" do expect(database.specfile_path).to eq Pathname("/non/sense/path/to/Gemfile") end end context "when the specfile_name is assigned" do let(:specfile_name) { "Sillyfile" } it "should give the assigned specfile path" do expect(database.specfile_path).to eq Pathname("/tmp/Sillyfile") end end end end