# encoding: utf-8 require 'spec_helper' require 'fedux_org_stdlib/app_config' RSpec.describe AppConfig do context 'options' do it 'creates readers and writers' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do option :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to be_nil config.opt1 = 'blub' expect(config.opt1).to eq 'blub' end end it 'creates readers' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to be_nil silence :stderr do expect { config.opt1 = 'blub' }.to raise_error NoMethodError end end end it 'checks for reserved key words' do with_environment 'HOME' => working_directory do expect do Class.new(AppConfig) do option_reader :_config_file, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end end.to raise_error FeduxOrgStdlib::AppConfig::Exceptions::OptionNameForbidden end end end context '#lock' do it 'raises error if config is locked and one tries to modify a config option' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do option :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new config.lock expect { config.opt1 = 1 }.to raise_error FeduxOrgStdlib::AppConfig::Exceptions::ConfigLocked end end end context '#preferred_configuration_file' do it 'has a default configuration file which is the preferred place to store the configuration' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.preferred_configuration_file).to eq File.expand_path('~/.config/my_application/tests.yaml') end end it 'works with nested module names' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do def _class_name 'TestConfig' end def _module_name 'MyApplication::MySub' end end config = config_klass.new expect(config.preferred_configuration_file).to eq File.expand_path('~/.config/my_application/my_sub/tests.yaml') end end end context 'config files' do it 'looks at ~/.test.yaml' do with_environment 'HOME' => working_directory do create_file '.tests.yaml', <<-EOS.strip_heredoc --- opt1: hello world EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'looks at ~/.config/my_application/tests.yaml' do with_environment 'HOME' => working_directory do create_file '.config/my_application/tests.yaml', <<-EOS.strip_heredoc --- opt1: hello world EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'looks at ~/.my_application/tests.yaml' do with_environment 'HOME' => working_directory do create_file '.my_application/tests.yaml', <<-EOS.strip_heredoc --- opt1: hello world EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'looks at ~/.tests.yaml' do with_environment 'HOME' => working_directory do create_file '.tests.yaml', <<-EOS.strip_heredoc --- opt1: hello world EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'looks at ~/.testsrc' do with_environment 'HOME' => working_directory do create_file '.testsrc', <<-EOS.strip_heredoc --- opt1: hello world EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'loads yaml files with the following data types' do with_environment 'HOME' => working_directory do create_file '.testsrc', <<-EOS.strip_heredoc --- opt1: hello world opt2: :test opt3: 1 opt4: true opt5: false opt6: - a - b opt7: name: berni EOS config_klass = Class.new(AppConfig) do option_reader :opt1, nil option_reader :opt2, nil option_reader :opt3, nil option_reader :opt4, nil option_reader :opt5, nil option_reader :opt6, nil option_reader :opt7, nil def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.opt1).to eq 'hello world' end end it 'raises error on invalid yaml file' do with_environment 'HOME' => working_directory do create_file '.testsrc', random_binary_string(100) config_klass = Class.new(AppConfig) do def _class_name 'TestConfig' end def _module_name 'MyApplication' end end expect { config_klass.new }.to raise_error FeduxOrgStdlib::AppConfig::Exceptions::ConfigFileNotReadable end end it 'returns an empty config if data file cannot be transformed to hash' do with_environment 'HOME' => working_directory do create_file '.testsrc', <<-EOS.strip_heredoc --- - hello - world EOS config_klass = Class.new(AppConfig) do def _class_name 'TestConfig' end def _module_name 'MyApplication' end end result = capture :stderr do config_klass.new end expect(result).to include "There seems" end end end context '#to_s' do it 'outputs a list of variables' do with_environment 'HOME' => working_directory do config_klass = Class.new(AppConfig) do option :opt1, 'test1' option :opt2, 'test2' option :opt3, { opt1: 'test1', opt2: 'test2' } def _class_name 'TestConfig' end def _module_name 'MyApplication' end end config = config_klass.new expect(config.to_s).to eq <<-EOS.strip_heredoc.chomp option | value ------ + -------------------------------------------------------------------------------- opt1 | "test1" opt2 | "test2" opt3 | "opt1: test1", "opt2: test2" EOS end end end end