qonfig 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -2
- data/.rubocop.yml +19 -1
- data/.travis.yml +7 -2
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +102 -0
- data/README.md +2 -0
- data/gemfiles/with_external_deps.gemfile.lock +112 -0
- data/gemfiles/without_external_deps.gemfile.lock +102 -0
- data/lib/qonfig.rb +1 -1
- data/lib/qonfig/commands/definition/load_from_env.rb +2 -0
- data/lib/qonfig/commands/definition/load_from_env/value_converter.rb +2 -0
- data/lib/qonfig/imports/direct_key.rb +8 -2
- data/lib/qonfig/imports/mappings.rb +8 -2
- data/lib/qonfig/loaders/basic.rb +2 -0
- data/lib/qonfig/loaders/json.rb +2 -1
- data/lib/qonfig/settings.rb +5 -1
- data/lib/qonfig/settings/key_matcher.rb +1 -1
- data/lib/qonfig/uploaders/base.rb +2 -0
- data/lib/qonfig/uploaders/yaml.rb +2 -0
- data/lib/qonfig/version.rb +1 -1
- data/qonfig.gemspec +4 -6
- data/sig/.keep +0 -0
- data/spec/features/clear_options_spec.rb +92 -0
- data/spec/features/compacted_config_spec.rb +308 -0
- data/spec/features/composition_spec.rb +207 -0
- data/spec/features/config_definition_and_representation_spec.rb +535 -0
- data/spec/features/definition_order_spec.rb +69 -0
- data/spec/features/dig_functionality_spec.rb +47 -0
- data/spec/features/dot_notation_spec.rb +159 -0
- data/spec/features/export_settings_spec.rb +138 -0
- data/spec/features/expose_json_spec.rb +281 -0
- data/spec/features/expose_self/format_option_dynamic_spec.rb +69 -0
- data/spec/features/expose_self/format_option_json_spec.rb +74 -0
- data/spec/features/expose_self/format_option_unsupported_spec.rb +27 -0
- data/spec/features/expose_self/format_option_yaml_spec.rb +77 -0
- data/spec/features/expose_self_spec.rb +97 -0
- data/spec/features/expose_yaml_spec.rb +263 -0
- data/spec/features/freeze_state_spec.rb +122 -0
- data/spec/features/get_config_keys_spec.rb +62 -0
- data/spec/features/get_config_values_spec.rb +41 -0
- data/spec/features/has_a_key_spec.rb +48 -0
- data/spec/features/import_settings_spec.rb +323 -0
- data/spec/features/indifferent_access_spec.rb +57 -0
- data/spec/features/inheritance_spec.rb +110 -0
- data/spec/features/instantiation_without_class_definition_spec.rb +59 -0
- data/spec/features/iteration_over_setting_keys_spec.rb +48 -0
- data/spec/features/load_from_env_spec.rb +240 -0
- data/spec/features/load_from_json_spec.rb +97 -0
- data/spec/features/load_from_self/format_option_json_spec.rb +31 -0
- data/spec/features/load_from_self/format_option_unsupported_spec.rb +27 -0
- data/spec/features/load_from_self/format_option_yaml_spec.rb +49 -0
- data/spec/features/load_from_self/with_erb_instructions_spec.rb +33 -0
- data/spec/features/load_from_self/with_hash_like_data_representation_spec.rb +66 -0
- data/spec/features/load_from_self/with_non_hash_like_data_representation_spec.rb +19 -0
- data/spec/features/load_from_self/without_end_data_spec.rb +11 -0
- data/spec/features/load_from_yaml_spec.rb +110 -0
- data/spec/features/load_setting_values_from_file/by_instance_method_examples.rb +171 -0
- data/spec/features/load_setting_values_from_file/by_macros_examples.rb +165 -0
- data/spec/features/load_setting_values_from_file/load_from_json_spec.rb +21 -0
- data/spec/features/load_setting_values_from_file/load_from_self/json_format/end_data_with_env_spec.rb +100 -0
- data/spec/features/load_setting_values_from_file/load_from_self/json_format/with_end_data_spec.rb +129 -0
- data/spec/features/load_setting_values_from_file/load_from_self/json_format/with_incorrect_end_data_spec.rb +34 -0
- data/spec/features/load_setting_values_from_file/load_from_self/json_format/without_end_data_spec.rb +65 -0
- data/spec/features/load_setting_values_from_file/load_from_self/yaml_format/end_data_with_env_spec.rb +94 -0
- data/spec/features/load_setting_values_from_file/load_from_self/yaml_format/with_end_data_spec.rb +126 -0
- data/spec/features/load_setting_values_from_file/load_from_self/yaml_format/with_incorrect_end_data_spec.rb +32 -0
- data/spec/features/load_setting_values_from_file/load_from_self/yaml_format/without_end_data_spec.rb +65 -0
- data/spec/features/load_setting_values_from_file/load_from_yaml_spec.rb +21 -0
- data/spec/features/load_setting_values_from_file/shared_behavior_spec.rb +33 -0
- data/spec/features/mixin_spec.rb +387 -0
- data/spec/features/non_redefineable_core_methods_spec.rb +29 -0
- data/spec/features/plugins/pretty_print_spec.rb +86 -0
- data/spec/features/plugins/toml/expose_self/format_option_toml_spec.rb +71 -0
- data/spec/features/plugins/toml/expose_toml_spec.rb +221 -0
- data/spec/features/plugins/toml/load_from_self/format_option_toml_spec.rb +27 -0
- data/spec/features/plugins/toml/load_from_toml_spec.rb +109 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/load_from_toml_spec.rb +27 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/load_toml_from_self/end_data_with_env_spec.rb +95 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/load_toml_from_self/with_end_data_spec.rb +125 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/load_toml_from_self/with_incorrect_end_data_spec.rb +34 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/load_toml_from_self/without_end_data_spec.rb +65 -0
- data/spec/features/plugins/toml/load_setting_values_from_file/shared_behavior_spec.rb +34 -0
- data/spec/features/plugins/toml/save_to_toml_spec.rb +149 -0
- data/spec/features/plugins/vault/expose_vault_spec.rb +117 -0
- data/spec/features/plugins/vault/load_from_vault_spec.rb +80 -0
- data/spec/features/plugins_spec.rb +89 -0
- data/spec/features/reload_spec.rb +75 -0
- data/spec/features/run_code_with_temporary_settings_spec.rb +104 -0
- data/spec/features/save_to_file/save_to_json_spec.rb +157 -0
- data/spec/features/save_to_file/save_to_yaml_spec.rb +189 -0
- data/spec/features/settings_as_predicates_spec.rb +47 -0
- data/spec/features/settings_redefinition_spec.rb +30 -0
- data/spec/features/slice_functionality_spec.rb +69 -0
- data/spec/features/subset_functionality_spec.rb +49 -0
- data/spec/features/validation_spec.rb +916 -0
- data/spec/fixtures/array_settings.yml +3 -0
- data/spec/fixtures/expose_json/incompatible_root_structure.json +6 -0
- data/spec/fixtures/expose_json/incompatible_structure.json +4 -0
- data/spec/fixtures/expose_json/project.development.json +7 -0
- data/spec/fixtures/expose_json/project.json +30 -0
- data/spec/fixtures/expose_json/project.production.json +7 -0
- data/spec/fixtures/expose_json/project.staging.json +7 -0
- data/spec/fixtures/expose_json/project.test.json +7 -0
- data/spec/fixtures/expose_yaml/incompatible_structure.yml +2 -0
- data/spec/fixtures/expose_yaml/project.development.yml +4 -0
- data/spec/fixtures/expose_yaml/project.production.yml +4 -0
- data/spec/fixtures/expose_yaml/project.staging.yml +4 -0
- data/spec/fixtures/expose_yaml/project.test.yml +4 -0
- data/spec/fixtures/expose_yaml/project.yml +25 -0
- data/spec/fixtures/json_array_sample.json +14 -0
- data/spec/fixtures/json_object_sample.json +9 -0
- data/spec/fixtures/json_with_empty_object.json +6 -0
- data/spec/fixtures/json_with_erb.json +6 -0
- data/spec/fixtures/plugins/toml/expose_toml/project.development.toml +4 -0
- data/spec/fixtures/plugins/toml/expose_toml/project.production.toml +4 -0
- data/spec/fixtures/plugins/toml/expose_toml/project.staging.toml +4 -0
- data/spec/fixtures/plugins/toml/expose_toml/project.test.toml +4 -0
- data/spec/fixtures/plugins/toml/expose_toml/project.toml +27 -0
- data/spec/fixtures/plugins/toml/mini_file.toml +6 -0
- data/spec/fixtures/plugins/toml/toml_sample_with_all_types.toml +72 -0
- data/spec/fixtures/plugins/toml/values_file/with_env.toml +13 -0
- data/spec/fixtures/plugins/toml/values_file/without_env.toml +6 -0
- data/spec/fixtures/rubocop_settings.yml +12 -0
- data/spec/fixtures/shared_settings_with_aliases.yml +10 -0
- data/spec/fixtures/travis_settings.yml +6 -0
- data/spec/fixtures/values_file/with_env.json +19 -0
- data/spec/fixtures/values_file/with_env.yml +17 -0
- data/spec/fixtures/values_file/without_env.json +8 -0
- data/spec/fixtures/values_file/without_env.yml +5 -0
- data/spec/fixtures/with_empty_hash.yml +4 -0
- data/spec/fixtures/with_erb_instructions.yml +3 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/meta_scopes.rb +20 -0
- data/spec/support/spec_support.rb +42 -0
- metadata +128 -11
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe 'Plugins(vault): expose vault', plugin: :vault do
|
|
4
|
+
before { stub_const('VaultConfig', vault_class) }
|
|
5
|
+
|
|
6
|
+
before { allow(Vault).to receive(:logical).and_return(logical_double) }
|
|
7
|
+
|
|
8
|
+
let(:logical_double) { instance_double(Vault::Logical) }
|
|
9
|
+
|
|
10
|
+
let(:returned_data) do
|
|
11
|
+
instance_double(Vault::Secret).tap do |instance|
|
|
12
|
+
allow(instance).to receive(:data).and_return(secret_data)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
let(:secret_data) do
|
|
16
|
+
{ data: { production: { kek: 'pek', cheburek: true }, other_key: '<%= 1 + 1 %>' } }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
let(:vault_class) do
|
|
20
|
+
Class.new(Qonfig::DataSet) do
|
|
21
|
+
setting :based_on_path do
|
|
22
|
+
expose_vault 'kv/data/path_based', via: :path, env: :production
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
setting :based_on_env_key do
|
|
26
|
+
expose_vault 'kv/data/env_key', via: :env_key, env: 'production'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
specify 'defines config object by vault instructions and specific environment settings' do
|
|
32
|
+
expect(Vault.logical).to(
|
|
33
|
+
receive(:read).with('kv/data/production/path_based').and_return(returned_data)
|
|
34
|
+
)
|
|
35
|
+
expect(Vault.logical).to receive(:read).with('kv/data/env_key').and_return(returned_data)
|
|
36
|
+
|
|
37
|
+
VaultConfig.new.settings.tap do |conf|
|
|
38
|
+
expect(conf.based_on_path.other_key).to eq(2)
|
|
39
|
+
expect(conf.based_on_path.production).to be_a(Qonfig::Settings)
|
|
40
|
+
expect(conf.based_on_env_key).to have_attributes(kek: 'pek', cheburek: true)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'when provided env argument is an Object' do
|
|
45
|
+
specify 'raises an error' do
|
|
46
|
+
expect do
|
|
47
|
+
Class.new(Qonfig::DataSet) do
|
|
48
|
+
expose_vault 'kv/data/path_based', via: Object.new, env: :production
|
|
49
|
+
end
|
|
50
|
+
end.to raise_error(Qonfig::ArgumentError)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when provided via argument is an Object' do
|
|
55
|
+
specify 'raises an error' do
|
|
56
|
+
expect do
|
|
57
|
+
Class.new(Qonfig::DataSet) do
|
|
58
|
+
expose_vault 'kv/data/path_based', via: :path, env: Object.new
|
|
59
|
+
end
|
|
60
|
+
end.to raise_error(Qonfig::ArgumentError)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'when provided via is not supported' do
|
|
65
|
+
specify 'raises an error' do
|
|
66
|
+
expect do
|
|
67
|
+
Class.new(Qonfig::DataSet) do
|
|
68
|
+
expose_vault 'kv/data/path_based', via: :kek, env: :production
|
|
69
|
+
end
|
|
70
|
+
end.to raise_error(Qonfig::ArgumentError)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context 'when provided env is empty' do
|
|
75
|
+
specify 'raises an error' do
|
|
76
|
+
expect do
|
|
77
|
+
Class.new(Qonfig::DataSet) do
|
|
78
|
+
expose_vault 'kv/data/path_based', via: :path, env: ''
|
|
79
|
+
end
|
|
80
|
+
end.to raise_error(Qonfig::ArgumentError)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "when provided key doesn't exist" do
|
|
85
|
+
let(:vault_class) do
|
|
86
|
+
Class.new(Qonfig::DataSet) do
|
|
87
|
+
expose_vault 'kv/data/env_key', via: :env_key, env: 'kekduction'
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
specify 'raises an error' do
|
|
92
|
+
expect(Vault.logical).to receive(:read).with('kv/data/env_key').and_return(returned_data)
|
|
93
|
+
|
|
94
|
+
expect { VaultConfig.new }.to raise_error(/does not contain settings with <kekduction>/)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'with not strict mode' do
|
|
99
|
+
let(:vault_class) do
|
|
100
|
+
Class.new(Qonfig::DataSet) do
|
|
101
|
+
setting :based_on_env_key do
|
|
102
|
+
expose_vault 'kv/data/env_key', via: :env_key, env: 'production', strict: false
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
let(:secret_data) { Hash[] }
|
|
108
|
+
|
|
109
|
+
specify "doesn't fail and uses empty config" do
|
|
110
|
+
expect(Vault.logical).to receive(:read).with('kv/data/env_key').and_return(returned_data)
|
|
111
|
+
|
|
112
|
+
conf = nil
|
|
113
|
+
expect { conf = VaultConfig.new }.not_to raise_error
|
|
114
|
+
expect(conf.to_h['based_on_env_key']).to be_empty
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe 'Plugins(vault): Load from vault kv store', plugin: :vault do
|
|
4
|
+
before { stub_const('VaultConfig', vault_class) }
|
|
5
|
+
|
|
6
|
+
before { allow(Vault).to receive(:logical).and_return(logical_double) }
|
|
7
|
+
|
|
8
|
+
let(:returned_data) do
|
|
9
|
+
instance_double(Vault::Secret).tap do |instance|
|
|
10
|
+
allow(instance).to receive(:data).and_return(secret_data)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
let(:logical_double) { instance_double(Vault::Logical) }
|
|
14
|
+
let(:secret_data) { Hash[data: { kek: true, pek: 'cheburek', nested: Hash[key: 123] }] }
|
|
15
|
+
|
|
16
|
+
let(:vault_class) do
|
|
17
|
+
Class.new(Qonfig::DataSet) do
|
|
18
|
+
load_from_vault 'kv/data/development'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
specify 'defines config object by vault instructions' do
|
|
23
|
+
expect(Vault.logical).to receive(:read).with('kv/data/development').and_return(returned_data)
|
|
24
|
+
|
|
25
|
+
VaultConfig.new.settings.tap do |conf|
|
|
26
|
+
expect(conf).to have_attributes(kek: true, pek: 'cheburek')
|
|
27
|
+
expect(conf.nested.key).to eq(123)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with not exist path' do
|
|
32
|
+
let(:expected_error_args) do
|
|
33
|
+
[Qonfig::FileNotFoundError, 'No such file or directory - Path kv/data/development not exist']
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
specify 'raises error' do
|
|
37
|
+
expect(Vault.logical).to receive(:read).with('kv/data/development').and_return(nil)
|
|
38
|
+
expect { VaultConfig.new }.to raise_error(*expected_error_args)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'with Pathname at path argument' do
|
|
43
|
+
let(:vault_class) do
|
|
44
|
+
Class.new(Qonfig::DataSet) do
|
|
45
|
+
load_from_vault Pathname('kv/data/development')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
specify 'converts it to string' do
|
|
50
|
+
expect(Vault.logical).to receive(:read).with('kv/data/development').and_return(returned_data)
|
|
51
|
+
|
|
52
|
+
VaultConfig.new
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'when strict set to false' do
|
|
57
|
+
let(:vault_class) do
|
|
58
|
+
Class.new(Qonfig::DataSet) do
|
|
59
|
+
load_from_vault 'kv/data/development', strict: false
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
specify "doesn't fail and uses empty config" do
|
|
64
|
+
expect(Vault.logical).to receive(:read).with('kv/data/development').and_return(nil).twice
|
|
65
|
+
|
|
66
|
+
expect { VaultConfig.new }.not_to raise_error
|
|
67
|
+
expect(VaultConfig.new.to_h).to eq({})
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when VaultError is raised' do
|
|
72
|
+
let(:raised_error) { Vault::VaultError.new('Cool error') }
|
|
73
|
+
|
|
74
|
+
specify 'raises VaultLoaderError' do
|
|
75
|
+
expect(Vault.logical).to receive(:read).with('kv/data/development').and_raise(raised_error)
|
|
76
|
+
|
|
77
|
+
expect { VaultConfig.new }.to raise_error(Qonfig::VaultLoaderError, 'Cool error')
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe 'Plugins' do
|
|
4
|
+
specify 'plguin regsitration, load and resolving' do
|
|
5
|
+
# plugins are not registered
|
|
6
|
+
expect(Qonfig::Plugins.names).not_to include('internal_test_plugin', 'external_test_plugin')
|
|
7
|
+
expect(Qonfig.plugins).not_to include('internal_test_plugin', 'external_test_plugin')
|
|
8
|
+
|
|
9
|
+
InternalTestPluginInterceptor = Class.new { def self.invoke; end }
|
|
10
|
+
ExternalTestPluginInterceptor = Class.new { def self.call; end }
|
|
11
|
+
|
|
12
|
+
module Qonfig::Plugins
|
|
13
|
+
class InternalTestPlugin < Abstract
|
|
14
|
+
def self.install!
|
|
15
|
+
InternalTestPluginInterceptor.invoke
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class ExternalTestPlugin < Abstract
|
|
20
|
+
def self.install!
|
|
21
|
+
ExternalTestPluginInterceptor.call
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# register new plugins
|
|
26
|
+
register_plugin(:internal_test_plugin, InternalTestPlugin)
|
|
27
|
+
register_plugin(:external_test_plugin, ExternalTestPlugin)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# plugins are registered
|
|
31
|
+
expect(Qonfig::Plugins.names).to include('internal_test_plugin', 'external_test_plugin')
|
|
32
|
+
expect(Qonfig.plugins).to include('internal_test_plugin', 'external_test_plugin')
|
|
33
|
+
|
|
34
|
+
# new plugins is not included in #loaded_plugins list
|
|
35
|
+
expect(Qonfig.loaded_plugins).not_to include('internal_test_plugin')
|
|
36
|
+
expect(Qonfig.loaded_plugins).not_to include('external_test_plugin')
|
|
37
|
+
expect(Qonfig.enabled_plugins).not_to include('internal_test_plugin')
|
|
38
|
+
expect(Qonfig.enabled_plugins).not_to include('external_test_plugin')
|
|
39
|
+
expect(Qonfig.loaded_plugins).to eq(Qonfig.enabled_plugins)
|
|
40
|
+
|
|
41
|
+
# plugin can be loaded
|
|
42
|
+
expect(InternalTestPluginInterceptor).to receive(:invoke).exactly(4).times
|
|
43
|
+
Qonfig::Plugins.load(:internal_test_plugin)
|
|
44
|
+
Qonfig::Plugins.load('internal_test_plugin')
|
|
45
|
+
Qonfig.plugin(:internal_test_plugin)
|
|
46
|
+
Qonfig.plugin('internal_test_plugin')
|
|
47
|
+
expect(Qonfig.loaded_plugins).to include('internal_test_plugin')
|
|
48
|
+
expect(Qonfig.loaded_plugins).not_to include('external_test_plugin')
|
|
49
|
+
expect(Qonfig.enabled_plugins).to include('internal_test_plugin')
|
|
50
|
+
expect(Qonfig.enabled_plugins).not_to include('external_test_plugin')
|
|
51
|
+
expect(Qonfig.loaded_plugins).to eq(Qonfig.enabled_plugins)
|
|
52
|
+
|
|
53
|
+
# plugin can be loaded
|
|
54
|
+
expect(ExternalTestPluginInterceptor).to receive(:call).exactly(4).times
|
|
55
|
+
Qonfig::Plugins.load(:external_test_plugin)
|
|
56
|
+
Qonfig::Plugins.load('external_test_plugin')
|
|
57
|
+
Qonfig.enable(:external_test_plugin)
|
|
58
|
+
Qonfig.enable('external_test_plugin')
|
|
59
|
+
expect(Qonfig.loaded_plugins).to include('external_test_plugin')
|
|
60
|
+
expect(Qonfig.loaded_plugins).to include('internal_test_plugin')
|
|
61
|
+
expect(Qonfig.enabled_plugins).to include('external_test_plugin')
|
|
62
|
+
expect(Qonfig.enabled_plugins).to include('internal_test_plugin')
|
|
63
|
+
expect(Qonfig.loaded_plugins).to eq(Qonfig.enabled_plugins)
|
|
64
|
+
|
|
65
|
+
# fails when there is an attempt to register a plugin with already used name
|
|
66
|
+
expect do
|
|
67
|
+
module Qonfig::Plugins
|
|
68
|
+
register_plugin(:internal_test_plugin, Object)
|
|
69
|
+
end
|
|
70
|
+
end.to raise_error(Qonfig::AlreadyRegisteredPluginError)
|
|
71
|
+
|
|
72
|
+
# fails when there is an attempt to register a plugin with already used name
|
|
73
|
+
expect do
|
|
74
|
+
module Qonfig::Plugins
|
|
75
|
+
register_plugin(:external_test_plugin, Object)
|
|
76
|
+
end
|
|
77
|
+
end.to raise_error(Qonfig::AlreadyRegisteredPluginError)
|
|
78
|
+
|
|
79
|
+
# fails when there is an attempt to load an unregistered plugin
|
|
80
|
+
expect do
|
|
81
|
+
Qonfig::Plugins.load(:kek_test_plugin)
|
|
82
|
+
end.to raise_error(Qonfig::UnregisteredPluginError)
|
|
83
|
+
|
|
84
|
+
# fails when there is an attempt to load an unregistered plugin
|
|
85
|
+
expect do
|
|
86
|
+
Qonfig.plugin(:kek_test_plugin)
|
|
87
|
+
end.to raise_error(Qonfig::UnregisteredPluginError)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe 'Config reloading' do
|
|
4
|
+
specify 'config reloading works correctly' do
|
|
5
|
+
class ReloadableConfig < Qonfig::DataSet
|
|
6
|
+
setting :db do
|
|
7
|
+
setting :adapter, 'postgresql'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
setting :logging, false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
config = ReloadableConfig.new
|
|
14
|
+
|
|
15
|
+
expect(config.to_h).to match(
|
|
16
|
+
'db' => { 'adapter' => 'postgresql' },
|
|
17
|
+
'logging' => false
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
config.configure { |conf| conf.logging = true } # change internal state
|
|
21
|
+
|
|
22
|
+
# re-define and append settings and validations
|
|
23
|
+
class ReloadableConfig
|
|
24
|
+
setting :db do
|
|
25
|
+
setting :adapter, 'mongoid' # re-define defaults
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
setting :enable_api, false # append new setting
|
|
29
|
+
|
|
30
|
+
validate :logging, :boolean, strict: true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
expect(config.to_h).to match(
|
|
34
|
+
'db' => { 'adapter' => 'postgresql' },
|
|
35
|
+
'logging' => true # internal state has initial value (not a changed previously)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# new validator is not invoked (logging should be a boolean)
|
|
39
|
+
expect { config.settings.logging = nil }.not_to raise_error
|
|
40
|
+
|
|
41
|
+
# reload config settings
|
|
42
|
+
config.reload!
|
|
43
|
+
|
|
44
|
+
expect(config.to_h).to match(
|
|
45
|
+
'db' => { 'adapter' => 'mongoid' },
|
|
46
|
+
'logging' => false,
|
|
47
|
+
'enable_api' => false
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# reload with instant configuration
|
|
51
|
+
config.reload! do |conf|
|
|
52
|
+
conf.enable_api = true # changed instantly
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
expect(config.to_h).to match(
|
|
56
|
+
'db' => { 'adapter' => 'mongoid' },
|
|
57
|
+
'logging' => false,
|
|
58
|
+
'enable_api' => true # value from isntant change
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# reload with hash && proc configuration
|
|
62
|
+
config.reload!(db: { adapter: 'oracloid' }) do |conf|
|
|
63
|
+
conf.enable_api = true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
expect(config.to_h).to match(
|
|
67
|
+
'db' => { 'adapter' => 'oracloid' },
|
|
68
|
+
'logging' => false,
|
|
69
|
+
'enable_api' => true
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# reload and set invalid options (logging cant be nil)
|
|
73
|
+
expect { config.reload!(logging: nil) }.to raise_error(Qonfig::ValidationError)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe 'Run code with temporary settings' do
|
|
4
|
+
specify 'temporary settings works as expected :)' do
|
|
5
|
+
config = Qonfig::DataSet.build do
|
|
6
|
+
setting :api do
|
|
7
|
+
setting :token, 'test123'
|
|
8
|
+
setting :login, 'D@iVeR'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
config.with(api: { token: '123test' }) do
|
|
13
|
+
config.settings.api.login = '555'
|
|
14
|
+
|
|
15
|
+
# NOTE: settings was changed
|
|
16
|
+
expect(config.settings.api.token).to eq('123test')
|
|
17
|
+
expect(config.settings.api.login).to eq('555')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# NOTE: original settings are still original :)
|
|
21
|
+
expect(config.settings.api.token).to eq('test123')
|
|
22
|
+
expect(config.settings.api.login).to eq('D@iVeR')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
specify 'thread-safety' do
|
|
26
|
+
config = Qonfig::DataSet.build do
|
|
27
|
+
setting :api do
|
|
28
|
+
setting :token, 'test123'
|
|
29
|
+
setting :login, 'D@iVeR'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
setting :credentials do
|
|
33
|
+
setting :user, 'admin'
|
|
34
|
+
setting :password, '1234asdf'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
ThreadGroup.new.tap do |thread_group|
|
|
39
|
+
10.times do
|
|
40
|
+
thread_group.add(Thread.new do
|
|
41
|
+
# NOTE: change settings temporary
|
|
42
|
+
config.with(api: { token: '777555' }, credentials: { password: 'test123' }) do
|
|
43
|
+
config.settings.credentials.user = 'nimda'
|
|
44
|
+
end
|
|
45
|
+
end)
|
|
46
|
+
|
|
47
|
+
thread_group.add(Thread.new do
|
|
48
|
+
# NOTE: settings are not changed :)
|
|
49
|
+
expect(config.settings.credentials.user).to eq('admin')
|
|
50
|
+
expect(config.settings.credentials.password).to eq('1234asdf')
|
|
51
|
+
expect(config.settings.api.token).to eq('test123')
|
|
52
|
+
expect(config.settings.api.login).to eq('D@iVeR')
|
|
53
|
+
end)
|
|
54
|
+
|
|
55
|
+
thread_group.add(Thread.new do
|
|
56
|
+
# NOTE: change settings temporary
|
|
57
|
+
config.with do
|
|
58
|
+
config.settings.api.login = 'provider'
|
|
59
|
+
config.settings.api.token = 'super_puper_123'
|
|
60
|
+
end
|
|
61
|
+
end)
|
|
62
|
+
|
|
63
|
+
thread_group.add(Thread.new do
|
|
64
|
+
# NOTE: settings are not changed :)
|
|
65
|
+
expect(config.settings.credentials.user).to eq('admin')
|
|
66
|
+
expect(config.settings.credentials.password).to eq('1234asdf')
|
|
67
|
+
expect(config.settings.api.token).to eq('test123')
|
|
68
|
+
expect(config.settings.api.login).to eq('D@iVeR')
|
|
69
|
+
end)
|
|
70
|
+
|
|
71
|
+
thread_group.add(Thread.new do
|
|
72
|
+
config.with(api: { login: '0exp' }, credentials: { user: 'D@iVeR' }) do
|
|
73
|
+
config.settings.api.token = 'kekpek123'
|
|
74
|
+
config.settings.credentials.password = 'admin'
|
|
75
|
+
end
|
|
76
|
+
end)
|
|
77
|
+
|
|
78
|
+
thread_group.add(Thread.new do
|
|
79
|
+
# NOTE: settings are not changed :)
|
|
80
|
+
expect(config.settings.credentials.user).to eq('admin')
|
|
81
|
+
expect(config.settings.credentials.password).to eq('1234asdf')
|
|
82
|
+
expect(config.settings.api.token).to eq('test123')
|
|
83
|
+
expect(config.settings.api.login).to eq('D@iVeR')
|
|
84
|
+
end)
|
|
85
|
+
|
|
86
|
+
thread_group.add(Thread.new do
|
|
87
|
+
# NOTE: change settings temporary
|
|
88
|
+
config.with(api: { login: 'mobile_legends' }, credentials: { user: 'dota2' }) do
|
|
89
|
+
config.settings.api.token = 'league_of_legends'
|
|
90
|
+
config.settings.credentials.password = 'overwatch'
|
|
91
|
+
end
|
|
92
|
+
end)
|
|
93
|
+
|
|
94
|
+
thread_group.add(Thread.new do
|
|
95
|
+
# NOTE: settings are not changed :)
|
|
96
|
+
expect(config.settings.credentials.user).to eq('admin')
|
|
97
|
+
expect(config.settings.credentials.password).to eq('1234asdf')
|
|
98
|
+
expect(config.settings.api.token).to eq('test123')
|
|
99
|
+
expect(config.settings.api.login).to eq('D@iVeR')
|
|
100
|
+
end)
|
|
101
|
+
end
|
|
102
|
+
end.list.map(&:join)
|
|
103
|
+
end
|
|
104
|
+
end
|