inspec/test/unit/utils/object_traversal_test.rb
Adam Leff 4f2b66302d Fix ObjectTraverser when accessing array values
When attempting to access array values via the `json` resource:

```
describe json('/tmp/test.json') do
      its(['array',0]) { should eq "zero" }
end
```

... the resulting data would be an array of the size of the original array
with all the values replaced with nils:

```
     expected: "zero"
          got: [nil, nil, nil]
```

This was due to a bug in the ObjectTraverser mixin that mapped array values
back through `extract_value` rather than properly handling the passed-in
key(s). This worked fine for the specific data format created by the `csv`
resource but did not work `json` or any other resource that subclassed the
`JsonConfig` resource.

This change fixes the logic when dealing with an array when it's encountered,
and fixes up the `csv` resource with its own `value` method.

This change also adds tests for ObjectTraverser.

Signed-off-by: Adam Leff <adam@leff.co>
2017-03-15 11:35:55 +01:00

80 lines
2.8 KiB
Ruby

# encoding: utf-8
# author: Adam Leff
require 'helper'
class Tester
include ObjectTraverser
end
describe ObjectTraverser do
let(:subject) { Tester.new }
let(:sample_data) do
{
'string1' => 'value1',
'string2' => 'value2',
'number1' => 2468,
'hash1' => { 'key1' => 'value1' },
'hash2' => {
'hash1string1' => 'value3',
'hash1number1' => 123,
'hash1subhash' => { 'key1' => 1, 'key2' => 2 },
},
'array1' => %w(word1 word2 word3),
'array2' => [
123,
456,
{ 'array1hashkey1' => 1, 'array1hashkey2' => 2 },
]
}
end
it 'returns values from the top-level' do
subject.extract_value(['string1'], sample_data).must_equal('value1')
subject.extract_value(['string2'], sample_data).must_equal('value2')
subject.extract_value(['number1'], sample_data).must_equal(2468)
end
it 'returns a full hash from the top-level' do
subject.extract_value(['hash1'], sample_data).must_equal({ 'key1' => 'value1' })
end
it 'returns values from a hash' do
subject.extract_value(['hash2', 'hash1string1'], sample_data).must_equal('value3')
subject.extract_value(['hash2', 'hash1number1'], sample_data).must_equal(123)
end
it 'returns values from a nested hash' do
subject.extract_value(['hash2', 'hash1subhash', 'key1'], sample_data).must_equal(1)
subject.extract_value(['hash2', 'hash1subhash', 'key2'], sample_data).must_equal(2)
end
it 'returns a full array from the top level' do
subject.extract_value(['array1'], sample_data).must_equal(%w(word1 word2 word3))
end
it 'returns values from the array using index numbers' do
subject.extract_value(['array1', 0], sample_data).must_equal('word1')
subject.extract_value(['array1', 1], sample_data).must_equal('word2')
subject.extract_value(['array1', 2], sample_data).must_equal('word3')
end
it 'returns values from the array using methods' do
subject.extract_value(['array1', 'first'], sample_data).must_equal('word1')
subject.extract_value(['array1', 'last'], sample_data).must_equal('word3')
end
it 'returns nil when fetching from an array when it does not match a method' do
subject.extract_value(['array1', 'not_a_valid_method'], sample_data).must_be_nil
end
it 'returns values from a nested hash within an array, accessing the array using numbers' do
subject.extract_value(['array2', 2, 'array1hashkey1'], sample_data).must_equal(1)
subject.extract_value(['array2', 2, 'array1hashkey2'], sample_data).must_equal(2)
end
it 'returns values from a nested hash within an array, accessing the array using methods' do
subject.extract_value(['array2', 'last', 'array1hashkey1'], sample_data).must_equal(1)
subject.extract_value(['array2', 'last', 'array1hashkey2'], sample_data).must_equal(2)
end
end