require 'dply/base_config' module Dply describe BaseConfig do before :all do @work_dir = "tmp/base_config" FileUtils.rm_rf @work_dir FileUtils.mkdir_p @work_dir conf_working conf_invalid_type conf_invalid_opt conf_missing_opts conf_override conf_other end class TestConfig < BaseConfig define_opts do opt :any opt :int, type: Integer opt :arr, type: Array opt :str1, type: String opt :str2, type: String end def default_config any "default_any" arr [:default] end end def conf_path(name) "#{@work_dir}/#{name}.rb" end def write_conf(name, data) File.write(conf_path(name), data) end def conf_working write_conf "working", <<~'EOF' any "1" int 2 arr [:myval] str1 { "#{any}#{int}#{str2}" } str2 "s2" EOF end def conf_other write_conf "other", <<~'EOF' any "4" any "3" EOF end def conf_invalid_type write_conf "invalid_type", <<~'EOF' any "1" int "2" EOF end def conf_invalid_opt write_conf "invalid_opt", <<~'EOF' other_opt "2" EOF end def conf_missing_opts write_conf "missing_opts", <<~'EOF' any "m" EOF end def conf_override write_conf "override", <<~'EOF' any "1" any { "override" } EOF end describe ".build" do it "parses the config and returns a struct" do path = conf_path "working" conf = TestConfig.build(path) expect(conf.any).to eq("1") expect(conf.int).to eq(2) expect(conf.arr).to eq([:myval]) expect(conf.str1).to eq("12s2") expect(conf.str2).to eq("s2") end it "calls default_config on opts_struct to set default values" do conf = TestConfig.build expect(conf.any).to eq("default_any") expect(conf.arr).to eq([:default]) end it "reads config using block" do path = conf_path "working" conf1 = TestConfig.build do read path end conf2 = TestConfig.build(path) expect(conf1.any).to eq(conf2.any) expect(conf2.str1).to eq(conf2.str1) end it "reads multiple configs(some can be optional) using block" do path = conf_path "working" other_path = conf_path "other" optional_path = "#{@work_dir}/missing.rb" conf = TestConfig.build do read optional_path, optional: true read path read other_path end expect(conf.any).to eq("3") expect(conf.int).to eq(2) expect(conf.arr).to eq([:myval]) expect(conf.str1).to eq("32s2") expect(conf.str2).to eq("s2") end it "raises error when config file is not readable" do path = "#{@work_dir}/missing.rb" expect { TestConfig.build(path) }.to raise_error(Error) end specify "config methods are available inside block" do path = conf_path "working" conf = TestConfig.build do read path any "45" str2 { "block_override" } end expect(conf.any).to eq("45") expect(conf.str2).to eq("block_override") end it "overrides values when using block setter" do path = conf_path "override" conf = TestConfig.build(path) expect(conf.any).to eq("override") end specify "set method works" do conf = TestConfig.build do set :any, "setval" end expect(conf.any).to eq("setval") end it "raises an error on invalid type" do path = conf_path "invalid_type" expect { TestConfig.build(path) }.to raise_error(Error, /Expected: /) end it "raises an error on invalid opt" do path = conf_path "invalid_opt" expect { TestConfig.build(path) }.to raise_error(Error, /invalid option/) end it "ignores missing options" do path = conf_path "missing_opts" conf = TestConfig.build path expect(conf.any).to eq("m") expect(conf.str2).to eq(nil) end end end end