a9n 0.6.2 → 0.7.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/.hound.yml +4 -0
- data/.rubocop.yml +43 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -3
- data/README.md +7 -7
- data/Rakefile +1 -2
- data/a9n.gemspec +14 -13
- data/lib/a9n.rb +29 -23
- data/lib/a9n/capistrano.rb +1 -1
- data/lib/a9n/capistrano/tasks.cap +3 -3
- data/lib/a9n/capistrano/ver2x.rb +2 -2
- data/lib/a9n/ext/hash.rb +4 -2
- data/lib/a9n/ext/string_inquirer.rb +2 -2
- data/lib/a9n/loader.rb +24 -19
- data/lib/a9n/scope.rb +2 -3
- data/lib/a9n/struct.rb +4 -2
- data/lib/a9n/version.rb +1 -1
- data/spec/integration/a9n_spec.rb +33 -33
- data/spec/spec_helper.rb +9 -12
- data/spec/unit/a9n_spec.rb +55 -55
- data/spec/unit/loader_spec.rb +71 -71
- data/spec/unit/scope_spec.rb +9 -9
- data/spec/unit/struct_spec.rb +68 -55
- data/test_app/benchmark.rb +4 -2
- metadata +26 -10
    
        data/spec/unit/loader_spec.rb
    CHANGED
    
    | @@ -1,89 +1,89 @@ | |
| 1 1 | 
             
            RSpec.describe A9n::Loader do
         | 
| 2 | 
            -
              let(:scope) { A9n::Scope.new( | 
| 3 | 
            -
              let(:env) {  | 
| 4 | 
            -
              let(:root) { File.expand_path( | 
| 5 | 
            -
              let(:file_path) { File.join(root,  | 
| 2 | 
            +
              let(:scope) { A9n::Scope.new('configuration') }
         | 
| 3 | 
            +
              let(:env) { 'test' }
         | 
| 4 | 
            +
              let(:root) { File.expand_path('../../test_app', __dir__) }
         | 
| 5 | 
            +
              let(:file_path) { File.join(root, 'config/configuration.yml') }
         | 
| 6 6 | 
             
              subject { described_class.new(file_path, scope, env) }
         | 
| 7 7 |  | 
| 8 | 
            -
              describe  | 
| 8 | 
            +
              describe '#intialize' do
         | 
| 9 9 | 
             
                it { expect(subject.scope).to eq(scope) }
         | 
| 10 10 | 
             
                it { expect(subject.env).to eq(env) }
         | 
| 11 11 | 
             
                it { expect(subject.local_file).to eq(file_path) }
         | 
| 12 12 | 
             
                it { expect(subject.example_file).to eq("#{file_path}.example") }
         | 
| 13 13 | 
             
              end
         | 
| 14 14 |  | 
| 15 | 
            -
              describe  | 
| 15 | 
            +
              describe '#load' do
         | 
| 16 16 | 
             
                let(:example_config) do
         | 
| 17 | 
            -
                  { app_url:  | 
| 17 | 
            +
                  { app_url: 'http://127.0.0.1:3000', api_key: 'example1234' }
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 20 | 
             
                let(:local_config) do
         | 
| 21 | 
            -
                  { app_host:  | 
| 21 | 
            +
                  { app_host: '127.0.0.1:3000', api_key: 'local1234' }
         | 
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| 24 | 
            -
                let(:env) {  | 
| 24 | 
            +
                let(:env) { 'tropical' }
         | 
| 25 25 | 
             
                let(:config) { subject.get }
         | 
| 26 26 |  | 
| 27 | 
            -
                context  | 
| 27 | 
            +
                context 'when no configuration file exists' do
         | 
| 28 28 | 
             
                  before do
         | 
| 29 29 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
         | 
| 30 30 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 | 
            -
                  it  | 
| 33 | 
            +
                  it 'raises expection' do
         | 
| 34 34 | 
             
                    expect {
         | 
| 35 35 | 
             
                      subject.load
         | 
| 36 36 | 
             
                    }.to raise_error(A9n::MissingConfigurationDataError)
         | 
| 37 37 | 
             
                  end
         | 
| 38 38 | 
             
                end
         | 
| 39 39 |  | 
| 40 | 
            -
                context  | 
| 40 | 
            +
                context 'when only example configuration file exists' do
         | 
| 41 41 | 
             
                  before do
         | 
| 42 42 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
         | 
| 43 43 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
         | 
| 44 44 | 
             
                    subject.load
         | 
| 45 45 | 
             
                  end
         | 
| 46 46 |  | 
| 47 | 
            -
                  it { expect(config.app_url).to eq( | 
| 48 | 
            -
                  it { expect(config.api_key).to eq( | 
| 47 | 
            +
                  it { expect(config.app_url).to eq('http://127.0.0.1:3000') }
         | 
| 48 | 
            +
                  it { expect(config.api_key).to eq('example1234') }
         | 
| 49 49 |  | 
| 50 50 | 
             
                  it do
         | 
| 51 51 | 
             
                    expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariableError)
         | 
| 52 52 | 
             
                  end
         | 
| 53 53 | 
             
                end
         | 
| 54 54 |  | 
| 55 | 
            -
                context  | 
| 55 | 
            +
                context 'when only local configuration file exists' do
         | 
| 56 56 | 
             
                  before do
         | 
| 57 57 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
         | 
| 58 58 | 
             
                    expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
         | 
| 59 59 | 
             
                    subject.load
         | 
| 60 60 | 
             
                  end
         | 
| 61 61 |  | 
| 62 | 
            -
                  it { expect(config.app_host).to eq( | 
| 63 | 
            -
                  it { expect(config.api_key).to eq( | 
| 62 | 
            +
                  it { expect(config.app_host).to eq('127.0.0.1:3000') }
         | 
| 63 | 
            +
                  it { expect(config.api_key).to eq('local1234') }
         | 
| 64 64 |  | 
| 65 65 | 
             
                  it do
         | 
| 66 66 | 
             
                    expect { config.app_url }.to raise_error(A9n::NoSuchConfigurationVariableError)
         | 
| 67 67 | 
             
                  end
         | 
| 68 68 | 
             
                end
         | 
| 69 69 |  | 
| 70 | 
            -
                context  | 
| 71 | 
            -
                  context  | 
| 70 | 
            +
                context 'when both local and base configuration file exists without defaults' do
         | 
| 71 | 
            +
                  context 'with same data' do
         | 
| 72 72 | 
             
                    before do
         | 
| 73 73 | 
             
                      expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
         | 
| 74 74 | 
             
                      expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(example_config)
         | 
| 75 75 | 
             
                      subject.load
         | 
| 76 76 | 
             
                    end
         | 
| 77 77 |  | 
| 78 | 
            -
                    it { expect(config.app_url).to eq( | 
| 79 | 
            -
                    it { expect(config.api_key).to eq( | 
| 78 | 
            +
                    it { expect(config.app_url).to eq('http://127.0.0.1:3000') }
         | 
| 79 | 
            +
                    it { expect(config.api_key).to eq('example1234') }
         | 
| 80 80 |  | 
| 81 81 | 
             
                    it do
         | 
| 82 82 | 
             
                      expect { config.app_host }.to raise_error(A9n::NoSuchConfigurationVariableError)
         | 
| 83 83 | 
             
                    end
         | 
| 84 84 | 
             
                  end
         | 
| 85 85 |  | 
| 86 | 
            -
                  context  | 
| 86 | 
            +
                  context 'with different data' do
         | 
| 87 87 | 
             
                    before do
         | 
| 88 88 | 
             
                      expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
         | 
| 89 89 | 
             
                      expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
         | 
| @@ -91,106 +91,106 @@ RSpec.describe A9n::Loader do | |
| 91 91 |  | 
| 92 92 | 
             
                    let(:missing_variables_names) { example_config.keys - local_config.keys }
         | 
| 93 93 |  | 
| 94 | 
            -
                    it  | 
| 94 | 
            +
                    it 'raises expection with missing variables names'  do
         | 
| 95 95 | 
             
                      expect {
         | 
| 96 96 | 
             
                        subject.load
         | 
| 97 | 
            -
                      }.to raise_error(A9n::MissingConfigurationVariablesError, /#{missing_variables_names.join( | 
| 97 | 
            +
                      }.to raise_error(A9n::MissingConfigurationVariablesError, /#{missing_variables_names.join(', ')}/)
         | 
| 98 98 | 
             
                    end
         | 
| 99 99 | 
             
                  end
         | 
| 100 100 | 
             
                end
         | 
| 101 101 | 
             
              end
         | 
| 102 102 |  | 
| 103 | 
            -
              describe  | 
| 104 | 
            -
                let(:env) {  | 
| 105 | 
            -
                subject { | 
| 103 | 
            +
              describe '.load_yml' do
         | 
| 104 | 
            +
                let(:env) { 'test' }
         | 
| 105 | 
            +
                subject { described_class.load_yml(file_path, scope, env) }
         | 
| 106 106 |  | 
| 107 | 
            -
                context  | 
| 108 | 
            -
                  let(:file_path) {  | 
| 107 | 
            +
                context 'when file not exists' do
         | 
| 108 | 
            +
                  let(:file_path) { 'file_not_existing_in_the_universe.yml' }
         | 
| 109 109 |  | 
| 110 | 
            -
                  it{ expect(subject).to be_nil }
         | 
| 110 | 
            +
                  it { expect(subject).to be_nil }
         | 
| 111 111 | 
             
                end
         | 
| 112 112 |  | 
| 113 | 
            -
                context  | 
| 114 | 
            -
                  shared_examples  | 
| 115 | 
            -
                    it  | 
| 113 | 
            +
                context 'when file exists' do
         | 
| 114 | 
            +
                  shared_examples 'non-empty config file' do
         | 
| 115 | 
            +
                    it 'returns non-empty hash' do
         | 
| 116 116 | 
             
                      expect(subject).to be_kind_of(Hash)
         | 
| 117 117 | 
             
                      expect(subject.keys).to_not be_empty
         | 
| 118 118 | 
             
                    end
         | 
| 119 119 | 
             
                  end
         | 
| 120 120 |  | 
| 121 121 | 
             
                  before do
         | 
| 122 | 
            -
                    ENV[ | 
| 123 | 
            -
                    ENV[ | 
| 122 | 
            +
                    ENV['ERB_DWARF'] = 'erbized dwarf'
         | 
| 123 | 
            +
                    ENV['DWARF_PASSWORD'] = 'dwarf123'
         | 
| 124 124 | 
             
                  end
         | 
| 125 125 |  | 
| 126 126 | 
             
                  after do
         | 
| 127 | 
            -
                    ENV.delete( | 
| 128 | 
            -
                    ENV.delete( | 
| 127 | 
            +
                    ENV.delete('ERB_DWARF')
         | 
| 128 | 
            +
                    ENV.delete('DWARF_PASSWORD')
         | 
| 129 129 | 
             
                  end
         | 
| 130 130 |  | 
| 131 | 
            -
                  context  | 
| 132 | 
            -
                    let(:file_path) { File.join(root,  | 
| 131 | 
            +
                  context 'when file has erb extension' do
         | 
| 132 | 
            +
                    let(:file_path) { File.join(root, 'config/a9n/cloud.yml.erb') }
         | 
| 133 133 |  | 
| 134 | 
            -
                    it_behaves_like  | 
| 134 | 
            +
                    it_behaves_like 'non-empty config file'
         | 
| 135 135 | 
             
                  end
         | 
| 136 136 |  | 
| 137 | 
            -
                  context  | 
| 138 | 
            -
                    let(:file_path) { File.join(root,  | 
| 137 | 
            +
                  context 'having env and defaults data' do
         | 
| 138 | 
            +
                    let(:file_path) { File.join(root, 'config/configuration.yml') }
         | 
| 139 139 |  | 
| 140 | 
            -
                    it_behaves_like  | 
| 140 | 
            +
                    it_behaves_like 'non-empty config file'
         | 
| 141 141 |  | 
| 142 | 
            -
                    it  | 
| 143 | 
            -
                      expect(subject[:default_dwarf]).to eq( | 
| 144 | 
            -
                      expect(subject[:overriden_dwarf]).to eq( | 
| 142 | 
            +
                    it 'contains keys from defaults scope' do
         | 
| 143 | 
            +
                      expect(subject[:default_dwarf]).to eq('default dwarf')
         | 
| 144 | 
            +
                      expect(subject[:overriden_dwarf]).to eq('already overriden dwarf')
         | 
| 145 145 | 
             
                    end
         | 
| 146 146 |  | 
| 147 | 
            -
                    it  | 
| 147 | 
            +
                    it 'has symbolized keys' do
         | 
| 148 148 | 
             
                      expect(subject.keys.first).to be_kind_of(Symbol)
         | 
| 149 149 | 
             
                      expect(subject[:hash_dwarf]).to be_kind_of(Hash)
         | 
| 150 150 | 
             
                      expect(subject[:hash_dwarf].keys.first).to be_kind_of(Symbol)
         | 
| 151 151 | 
             
                    end
         | 
| 152 152 |  | 
| 153 | 
            -
                    it  | 
| 154 | 
            -
                      expect(subject[:erb_dwarf]).to eq( | 
| 153 | 
            +
                    it 'parses erb' do
         | 
| 154 | 
            +
                      expect(subject[:erb_dwarf]).to eq('erbized dwarf')
         | 
| 155 155 | 
             
                    end
         | 
| 156 156 |  | 
| 157 | 
            -
                    it  | 
| 158 | 
            -
                      expect(subject[:dwarf_password]).to eq( | 
| 157 | 
            +
                    it 'gets valus from ENV' do
         | 
| 158 | 
            +
                      expect(subject[:dwarf_password]).to eq('dwarf123')
         | 
| 159 159 | 
             
                    end
         | 
| 160 160 |  | 
| 161 | 
            -
                    it  | 
| 162 | 
            -
                      ENV.delete( | 
| 163 | 
            -
                      expect{ subject[:dwarf_password] }.to raise_error(A9n::MissingEnvVariableError)
         | 
| 161 | 
            +
                    it 'raises exception when ENV var is not set' do
         | 
| 162 | 
            +
                      ENV.delete('DWARF_PASSWORD')
         | 
| 163 | 
            +
                      expect { subject[:dwarf_password] }.to raise_error(A9n::MissingEnvVariableError)
         | 
| 164 164 | 
             
                    end
         | 
| 165 165 |  | 
| 166 | 
            -
                    it  | 
| 167 | 
            -
                      ENV[ | 
| 168 | 
            -
                      expect{ subject[:dwarf_password] }.to raise_error(A9n::MissingEnvVariableError)
         | 
| 166 | 
            +
                    it 'raises exception when ENV var is set to nil' do
         | 
| 167 | 
            +
                      ENV['DWARF_PASSWORD'] = nil
         | 
| 168 | 
            +
                      expect { subject[:dwarf_password] }.to raise_error(A9n::MissingEnvVariableError)
         | 
| 169 169 | 
             
                    end
         | 
| 170 170 | 
             
                  end
         | 
| 171 171 |  | 
| 172 | 
            -
                  context  | 
| 173 | 
            -
                    let(:file_path) { File.join(root,  | 
| 174 | 
            -
                    let(:env) {  | 
| 172 | 
            +
                  context 'having no env and only defaults data' do
         | 
| 173 | 
            +
                    let(:file_path) { File.join(root, 'config/configuration.yml') }
         | 
| 174 | 
            +
                    let(:env) { 'production' }
         | 
| 175 175 |  | 
| 176 | 
            -
                    it_behaves_like  | 
| 176 | 
            +
                    it_behaves_like 'non-empty config file'
         | 
| 177 177 |  | 
| 178 | 
            -
                    it  | 
| 179 | 
            -
                      expect(subject[:default_dwarf]).to eq( | 
| 180 | 
            -
                      expect(subject[:overriden_dwarf]).to eq( | 
| 178 | 
            +
                    it 'contains keys from defaults scope' do
         | 
| 179 | 
            +
                      expect(subject[:default_dwarf]).to eq('default dwarf')
         | 
| 180 | 
            +
                      expect(subject[:overriden_dwarf]).to eq('not yet overriden dwarf')
         | 
| 181 181 | 
             
                    end
         | 
| 182 182 | 
             
                  end
         | 
| 183 183 |  | 
| 184 | 
            -
                  context  | 
| 185 | 
            -
                    let(:file_path) { File.join(root,  | 
| 184 | 
            +
                  context 'having only env and no default data' do
         | 
| 185 | 
            +
                    let(:file_path) { File.join(root, 'config/no_defaults.yml') }
         | 
| 186 186 |  | 
| 187 | 
            -
                    context  | 
| 188 | 
            -
                      let(:env) {  | 
| 189 | 
            -
                      it_behaves_like  | 
| 187 | 
            +
                    context 'valid env' do
         | 
| 188 | 
            +
                      let(:env) { 'production' }
         | 
| 189 | 
            +
                      it_behaves_like 'non-empty config file'
         | 
| 190 190 | 
             
                    end
         | 
| 191 191 |  | 
| 192 | 
            -
                    context  | 
| 193 | 
            -
                      let(:env) {  | 
| 192 | 
            +
                    context 'invalid env' do
         | 
| 193 | 
            +
                      let(:env) { 'tropical' }
         | 
| 194 194 | 
             
                      it { expect(subject).to be_nil }
         | 
| 195 195 | 
             
                    end
         | 
| 196 196 | 
             
                  end
         | 
    
        data/spec/unit/scope_spec.rb
    CHANGED
    
    | @@ -1,25 +1,25 @@ | |
| 1 1 | 
             
            RSpec.describe A9n::Scope do
         | 
| 2 2 | 
             
              subject { described_class.new(name) }
         | 
| 3 3 |  | 
| 4 | 
            -
              describe  | 
| 5 | 
            -
                let(:name) {  | 
| 4 | 
            +
              describe '#name' do
         | 
| 5 | 
            +
                let(:name) { 'configuration' }
         | 
| 6 6 | 
             
                it { expect(subject.name).to eq(:configuration) }
         | 
| 7 7 | 
             
              end
         | 
| 8 8 |  | 
| 9 | 
            -
              describe  | 
| 10 | 
            -
                context  | 
| 11 | 
            -
                  let(:name) {  | 
| 9 | 
            +
              describe '#main?' do
         | 
| 10 | 
            +
                context 'when name is configuration' do
         | 
| 11 | 
            +
                  let(:name) { 'configuration' }
         | 
| 12 12 | 
             
                  it { expect(subject).to be_root }
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 | 
            -
                context  | 
| 16 | 
            -
                  let(:name) {  | 
| 15 | 
            +
                context 'when name is other than configuration' do
         | 
| 16 | 
            +
                  let(:name) { 'mandrill' }
         | 
| 17 17 | 
             
                  it { expect(subject).not_to be_root }
         | 
| 18 18 | 
             
                end
         | 
| 19 19 | 
             
              end
         | 
| 20 20 |  | 
| 21 | 
            -
              describe  | 
| 22 | 
            -
                let(:path) {  | 
| 21 | 
            +
              describe '.form_file_path' do
         | 
| 22 | 
            +
                let(:path) { 'config/a9n/mandrill.yml.example' }
         | 
| 23 23 | 
             
                subject { described_class.form_file_path(path) }
         | 
| 24 24 |  | 
| 25 25 | 
             
                it { expect(subject.name).to eq(:mandrill) }
         | 
    
        data/spec/unit/struct_spec.rb
    CHANGED
    
    | @@ -1,151 +1,164 @@ | |
| 1 1 | 
             
            RSpec.describe A9n::Struct do
         | 
| 2 | 
            -
              context  | 
| 2 | 
            +
              context 'without any values' do
         | 
| 3 3 | 
             
                subject { described_class.new }
         | 
| 4 4 |  | 
| 5 | 
            -
                describe  | 
| 5 | 
            +
                describe '#empty?' do
         | 
| 6 6 | 
             
                  it { expect(subject).to be_empty }
         | 
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 | 
            -
                describe  | 
| 9 | 
            +
                describe '#keys' do
         | 
| 10 10 | 
             
                  it { expect(subject.keys).to eq([]) }
         | 
| 11 11 | 
             
                end
         | 
| 12 12 |  | 
| 13 | 
            -
                describe  | 
| 13 | 
            +
                describe '#key?' do
         | 
| 14 14 | 
             
                  it { expect(subject.key?(:dwarf)).to eq(false) }
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 | 
            -
                describe  | 
| 17 | 
            +
                describe '#[]' do
         | 
| 18 18 | 
             
                  it { expect(subject[:dwarf]).to eq(nil) }
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| 21 | 
            -
                describe  | 
| 21 | 
            +
                describe '#fetch' do
         | 
| 22 22 | 
             
                  it do
         | 
| 23 | 
            -
                    expect {
         | 
| 24 | 
            -
                      subject.fetch(:dwarf)
         | 
| 25 | 
            -
                    }.to raise_error(KeyError)
         | 
| 23 | 
            +
                    expect { subject.fetch(:dwarf) }.to raise_error(KeyError)
         | 
| 26 24 | 
             
                  end
         | 
| 27 25 |  | 
| 28 26 | 
             
                  it do
         | 
| 29 | 
            -
                    expect(subject.fetch(:dwarf,  | 
| 27 | 
            +
                    expect(subject.fetch(:dwarf, 'hello')).to eq('hello')
         | 
| 30 28 | 
             
                  end
         | 
| 31 29 | 
             
                end
         | 
| 32 30 |  | 
| 33 | 
            -
                it  | 
| 31 | 
            +
                it 'raises error on accessin invalid attribute' do
         | 
| 34 32 | 
             
                  expect {
         | 
| 35 33 | 
             
                    subject.dwarf
         | 
| 36 | 
            -
                  }.to raise_error(A9n::NoSuchConfigurationVariableError,  | 
| 34 | 
            +
                  }.to raise_error(A9n::NoSuchConfigurationVariableError, 'dwarf')
         | 
| 37 35 | 
             
                end
         | 
| 38 36 | 
             
              end
         | 
| 39 37 |  | 
| 40 | 
            -
              context  | 
| 41 | 
            -
                 | 
| 42 | 
            -
                   | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
                 | 
| 50 | 
            -
             | 
| 51 | 
            -
                 | 
| 38 | 
            +
              context 'with values' do
         | 
| 39 | 
            +
                let(:data) do
         | 
| 40 | 
            +
                  {
         | 
| 41 | 
            +
                    non_empty_dwarf: 'dwarf',
         | 
| 42 | 
            +
                    nil_dwarf: nil,
         | 
| 43 | 
            +
                    false_dwarf: false,
         | 
| 44 | 
            +
                    true_dwarf: true,
         | 
| 45 | 
            +
                    hash_dwarf: { dwarf: 'hello' }
         | 
| 46 | 
            +
                  }
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                subject { described_class.new(data) }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                describe '#keys' do
         | 
| 52 52 | 
             
                  it do
         | 
| 53 53 | 
             
                    expect(subject.keys).to eq [:non_empty_dwarf, :nil_dwarf, :false_dwarf, :true_dwarf, :hash_dwarf]
         | 
| 54 54 | 
             
                  end
         | 
| 55 55 | 
             
                end
         | 
| 56 56 |  | 
| 57 | 
            -
                describe  | 
| 57 | 
            +
                describe '#to_h' do
         | 
| 58 | 
            +
                  it do
         | 
| 59 | 
            +
                    expect(subject.to_h).to be_kind_of(Hash)
         | 
| 60 | 
            +
                    expect(subject.to_h).to eq(data)
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                describe '#to_hash' do
         | 
| 65 | 
            +
                  it do
         | 
| 66 | 
            +
                    expect(subject.to_hash).to be_kind_of(Hash)
         | 
| 67 | 
            +
                    expect(subject.to_hash).to eq(data)
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                describe '#key?' do
         | 
| 58 72 | 
             
                  it { expect(subject.key?(:nil_dwarf)).to eq(true) }
         | 
| 59 73 | 
             
                  it { expect(subject.key?(:unknown)).to eq(false) }
         | 
| 60 74 | 
             
                end
         | 
| 61 75 |  | 
| 62 | 
            -
                describe  | 
| 76 | 
            +
                describe '#merge' do
         | 
| 63 77 | 
             
                  before { subject.merge(argument) }
         | 
| 64 78 |  | 
| 65 | 
            -
                  context  | 
| 66 | 
            -
                    let(:argument) { { non_empty_dwarf:  | 
| 79 | 
            +
                  context 'hash' do
         | 
| 80 | 
            +
                    let(:argument) { { non_empty_dwarf: 'hello dwarf' } }
         | 
| 67 81 |  | 
| 68 82 | 
             
                    it do
         | 
| 69 | 
            -
                      expect(subject.non_empty_dwarf).to eq( | 
| 83 | 
            +
                      expect(subject.non_empty_dwarf).to eq('hello dwarf')
         | 
| 70 84 | 
             
                    end
         | 
| 71 85 | 
             
                  end
         | 
| 72 86 |  | 
| 73 | 
            -
                  context  | 
| 74 | 
            -
                    let(:argument) { described_class.new(non_empty_dwarf:  | 
| 87 | 
            +
                  context 'struct' do
         | 
| 88 | 
            +
                    let(:argument) { described_class.new(non_empty_dwarf: 'hello dwarf') }
         | 
| 75 89 |  | 
| 76 90 | 
             
                    it do
         | 
| 77 | 
            -
                      expect(subject.non_empty_dwarf).to eq( | 
| 91 | 
            +
                      expect(subject.non_empty_dwarf).to eq('hello dwarf')
         | 
| 78 92 | 
             
                    end
         | 
| 79 93 | 
             
                  end
         | 
| 80 94 | 
             
                end
         | 
| 81 95 |  | 
| 82 | 
            -
                it  | 
| 96 | 
            +
                it 'is not empty' do
         | 
| 83 97 | 
             
                  expect(subject).not_to be_empty
         | 
| 84 98 | 
             
                end
         | 
| 85 99 |  | 
| 86 | 
            -
                it  | 
| 87 | 
            -
                  expect(subject.non_empty_dwarf).to eq( | 
| 100 | 
            +
                it 'gets non-empty value' do
         | 
| 101 | 
            +
                  expect(subject.non_empty_dwarf).to eq('dwarf')
         | 
| 88 102 | 
             
                end
         | 
| 89 103 |  | 
| 90 | 
            -
                it  | 
| 104 | 
            +
                it 'gets nil value' do
         | 
| 91 105 | 
             
                  expect(subject.nil_dwarf).to eq(nil)
         | 
| 92 106 | 
             
                end
         | 
| 93 107 |  | 
| 94 | 
            -
                it  | 
| 108 | 
            +
                it 'gets true value' do
         | 
| 95 109 | 
             
                  expect(subject.true_dwarf).to eq(true)
         | 
| 96 110 | 
             
                end
         | 
| 97 111 |  | 
| 98 | 
            -
                it  | 
| 112 | 
            +
                it 'gets false value' do
         | 
| 99 113 | 
             
                  expect(subject.false_dwarf).to eq(false)
         | 
| 100 114 | 
             
                end
         | 
| 101 115 |  | 
| 102 | 
            -
                it  | 
| 116 | 
            +
                it 'gets hash value' do
         | 
| 103 117 | 
             
                  expect(subject.hash_dwarf).to be_kind_of(Hash)
         | 
| 104 118 | 
             
                end
         | 
| 105 119 |  | 
| 106 | 
            -
                it  | 
| 120 | 
            +
                it 'raises exception when value not exists' do
         | 
| 107 121 | 
             
                  expect {
         | 
| 108 122 | 
             
                    subject.non_existing_dwarf
         | 
| 109 123 | 
             
                  }.to raise_error(A9n::NoSuchConfigurationVariableError)
         | 
| 110 124 | 
             
                end
         | 
| 111 125 |  | 
| 112 | 
            -
                describe  | 
| 113 | 
            -
                  it  | 
| 114 | 
            -
                    expect(subject[:non_empty_dwarf]).to eq( | 
| 126 | 
            +
                describe '#[]' do
         | 
| 127 | 
            +
                  it 'returns non empty value' do
         | 
| 128 | 
            +
                    expect(subject[:non_empty_dwarf]).to eq('dwarf')
         | 
| 115 129 | 
             
                  end
         | 
| 116 130 |  | 
| 117 | 
            -
                  it  | 
| 131 | 
            +
                  it 'returns false value' do
         | 
| 118 132 | 
             
                    expect(subject[:false_dwarf]).to eq(false)
         | 
| 119 133 | 
             
                  end
         | 
| 120 134 |  | 
| 121 | 
            -
                  it  | 
| 135 | 
            +
                  it 'returns nil value' do
         | 
| 122 136 | 
             
                    expect(subject[:nil_dwarf]).to eq(nil)
         | 
| 123 137 | 
             
                  end
         | 
| 124 138 |  | 
| 125 | 
            -
                  it  | 
| 139 | 
            +
                  it 'returns nil for non existing key' do
         | 
| 126 140 | 
             
                    expect(subject[:non_existing_dwarf]).to eq(nil)
         | 
| 127 141 | 
             
                  end
         | 
| 128 142 | 
             
                end
         | 
| 129 143 |  | 
| 130 | 
            -
             | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
                    expect(subject.fetch(:non_empty_dwarf)).to eq("dwarf")
         | 
| 144 | 
            +
                describe '#fetch' do
         | 
| 145 | 
            +
                  it 'returns non empty value' do
         | 
| 146 | 
            +
                    expect(subject.fetch(:non_empty_dwarf)).to eq('dwarf')
         | 
| 134 147 | 
             
                  end
         | 
| 135 148 |  | 
| 136 | 
            -
                  it  | 
| 149 | 
            +
                  it 'returns false value' do
         | 
| 137 150 | 
             
                    expect(subject.fetch(:false_dwarf)).to eq(false)
         | 
| 138 151 | 
             
                  end
         | 
| 139 152 |  | 
| 140 | 
            -
                  it  | 
| 153 | 
            +
                  it 'returns nil value' do
         | 
| 141 154 | 
             
                    expect(subject.fetch(:nil_dwarf)).to eq(nil)
         | 
| 142 155 | 
             
                  end
         | 
| 143 156 |  | 
| 144 | 
            -
                  it  | 
| 145 | 
            -
                    expect(subject.fetch(:non_existing_dwarf,  | 
| 157 | 
            +
                  it 'returns default for non existing value' do
         | 
| 158 | 
            +
                    expect(subject.fetch(:non_existing_dwarf, 'hello')).to eq('hello')
         | 
| 146 159 | 
             
                  end
         | 
| 147 160 |  | 
| 148 | 
            -
                  it  | 
| 161 | 
            +
                  it 'raises error for non existing key' do
         | 
| 149 162 | 
             
                    expect {
         | 
| 150 163 | 
             
                      subject.fetch(:non_existing_dwarf)
         | 
| 151 164 | 
             
                    }.to raise_error(KeyError)
         |