vcloud-edge_gateway 0.2.2 → 0.2.3

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.
Files changed (34) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/README.md +219 -11
  3. data/examples/firewall-rules.yaml +50 -0
  4. data/examples/loadbalancer-rules.yaml +55 -0
  5. data/examples/nat-rules.yaml +58 -0
  6. data/lib/vcloud/edge_gateway.rb +2 -3
  7. data/lib/vcloud/edge_gateway/configuration_differ.rb +13 -1
  8. data/lib/vcloud/edge_gateway/configuration_generator/nat_service.rb +10 -10
  9. data/lib/vcloud/edge_gateway/edge_gateway_configuration.rb +2 -2
  10. data/lib/vcloud/edge_gateway/firewall_configuration_differ.rb +18 -0
  11. data/lib/vcloud/edge_gateway/load_balancer_configuration_differ.rb +3 -13
  12. data/lib/vcloud/edge_gateway/nat_configuration_differ.rb +18 -0
  13. data/lib/vcloud/edge_gateway/version.rb +1 -1
  14. data/lib/vcloud/edge_gateway_services.rb +1 -1
  15. data/spec/integration/edge_gateway/edge_gateway_services_spec.rb +7 -13
  16. data/spec/integration/edge_gateway/firewall_service_spec.rb +2 -12
  17. data/spec/integration/edge_gateway/load_balancer_service_spec.rb +4 -4
  18. data/spec/integration/edge_gateway/nat_service_spec.rb +4 -4
  19. data/spec/spec_helper.rb +2 -2
  20. data/spec/vcloud/edge_gateway/configuration_differ_shared_examples.rb +132 -0
  21. data/spec/vcloud/edge_gateway/configuration_differ_spec.rb +5 -122
  22. data/spec/vcloud/edge_gateway/configuration_generator/firewall_service_spec.rb +46 -52
  23. data/spec/vcloud/edge_gateway/firewall_configuration_differ_spec.rb +65 -0
  24. data/spec/vcloud/edge_gateway/firewall_schema_validation_spec.rb +2 -2
  25. data/spec/vcloud/edge_gateway/load_balancer_configuration_differ_spec.rb +32 -147
  26. data/spec/vcloud/edge_gateway/load_balancer_schema_validation_spec.rb +7 -7
  27. data/spec/vcloud/edge_gateway/nat_configuration_differ_spec.rb +65 -0
  28. data/spec/vcloud/edge_gateway/nat_schema_validation_spec.rb +4 -4
  29. data/vcloud-edge_gateway.gemspec +2 -2
  30. metadata +18 -13
  31. data/lib/vcloud/config_loader.rb +0 -27
  32. data/lib/vcloud/config_validator.rb +0 -207
  33. data/spec/vcloud/config_loader_spec.rb +0 -112
  34. data/spec/vcloud/config_validator_spec.rb +0 -570
@@ -3,9 +3,6 @@ require 'vcloud/edge_gateway/version'
3
3
  require 'vcloud/core'
4
4
  require 'vcloud/fog'
5
5
 
6
- require 'vcloud/config_loader'
7
- require 'vcloud/config_validator'
8
-
9
6
  require 'vcloud/edge_gateway_services'
10
7
 
11
8
  require 'vcloud/schema/nat_service'
@@ -18,6 +15,8 @@ require 'vcloud/edge_gateway/configuration_generator/firewall_service'
18
15
  require 'vcloud/edge_gateway/configuration_generator/nat_service'
19
16
  require 'vcloud/edge_gateway/configuration_generator/load_balancer_service'
20
17
  require 'vcloud/edge_gateway/configuration_differ'
18
+ require 'vcloud/edge_gateway/nat_configuration_differ'
19
+ require 'vcloud/edge_gateway/firewall_configuration_differ'
21
20
  require 'vcloud/edge_gateway/load_balancer_configuration_differ'
22
21
  require 'vcloud/edge_gateway/edge_gateway_configuration'
23
22
 
@@ -8,7 +8,19 @@ module Vcloud
8
8
  end
9
9
 
10
10
  def diff
11
- ( @local == @remote ) ? [] : HashDiff.diff(@local, @remote)
11
+ ( stripped_local_config == stripped_remote_config ) ? [] : HashDiff.diff(stripped_local_config, stripped_remote_config)
12
+ end
13
+
14
+ def stripped_local_config
15
+ strip_fields_for_differ_to_ignore(@local) unless @local.nil?
16
+ end
17
+
18
+ def stripped_remote_config
19
+ strip_fields_for_differ_to_ignore(@remote) unless @remote.nil?
20
+ end
21
+
22
+ def strip_fields_for_differ_to_ignore(config)
23
+ config
12
24
  end
13
25
 
14
26
  end
@@ -19,16 +19,16 @@ module Vcloud
19
19
 
20
20
  def populate_nat_rules
21
21
  rules = @input_config[:nat_rules]
22
- i = ID_RANGES::NAT_SERVICE[:min]
23
- rules.collect do |rule|
24
- new_rule = {}
25
- new_rule[:Id] = rule.key?(:id) ? rule[:id] : i.to_s
26
- new_rule[:IsEnabled] = rule.key?(:enabled) ? rule[:enabled].to_s : 'true'
27
- new_rule[:RuleType] = rule[:rule_type]
28
- gateway_nat_rule = populate_gateway_nat_rule(rule)
29
- new_rule[:GatewayNatRule] = gateway_nat_rule
30
- i += 1
31
- new_rule
22
+ i = ID_RANGES::NAT_SERVICE[:min]
23
+ rules.collect do |rule|
24
+ new_rule = {}
25
+ new_rule[:Id] = rule.key?(:id) ? rule[:id] : i.to_s
26
+ new_rule[:IsEnabled] = rule.key?(:enabled) ? rule[:enabled].to_s : 'true'
27
+ new_rule[:RuleType] = rule[:rule_type]
28
+ gateway_nat_rule = populate_gateway_nat_rule(rule)
29
+ new_rule[:GatewayNatRule] = gateway_nat_rule
30
+ i += 1
31
+ new_rule
32
32
  end
33
33
  end
34
34
 
@@ -15,7 +15,7 @@ module Vcloud
15
15
 
16
16
  firewall_service_config = EdgeGateway::ConfigurationGenerator::FirewallService.new.generate_fog_config(@local_config[:firewall_service])
17
17
  unless firewall_service_config.nil?
18
- differ = EdgeGateway::ConfigurationDiffer.new(firewall_service_config, @remote_config[:FirewallService])
18
+ differ = EdgeGateway::FirewallConfigurationDiffer.new(firewall_service_config, @remote_config[:FirewallService])
19
19
  unless differ.diff.empty?
20
20
  @config[:FirewallService] = firewall_service_config
21
21
  @update_required = true
@@ -28,7 +28,7 @@ module Vcloud
28
28
  ).generate_fog_config
29
29
 
30
30
  unless nat_service_config.nil?
31
- differ = EdgeGateway::ConfigurationDiffer.new(nat_service_config, @remote_config[:NatService])
31
+ differ = EdgeGateway::NatConfigurationDiffer.new(nat_service_config, @remote_config[:NatService])
32
32
  unless differ.diff.empty?
33
33
  @config[:NatService] = nat_service_config
34
34
  @update_required = true
@@ -0,0 +1,18 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ class FirewallConfigurationDiffer < ConfigurationDiffer
4
+
5
+ def strip_fields_for_differ_to_ignore(config)
6
+ deep_cloned_config = Marshal.load( Marshal.dump(config) )
7
+ if deep_cloned_config.key?(:FirewallRule)
8
+ deep_cloned_config[:FirewallRule].each do |firewall_rule|
9
+ firewall_rule.delete(:Id)
10
+ end
11
+ end
12
+ deep_cloned_config
13
+ end
14
+
15
+ end
16
+ end
17
+
18
+ end
@@ -1,19 +1,9 @@
1
1
  module Vcloud
2
2
  module EdgeGateway
3
- class LoadBalancerConfigurationDiffer
3
+ class LoadBalancerConfigurationDiffer < ConfigurationDiffer
4
4
 
5
- def initialize local, remote
6
- @local = local
7
- @remote = remote
8
- end
9
-
10
- def diff
11
- ( @local == stripped_remote_config ) ? [] : HashDiff.diff(@local, stripped_remote_config)
12
- end
13
-
14
- def stripped_remote_config
15
- return nil if @remote.nil?
16
- deep_cloned_remote_config = Marshal.load( Marshal.dump(@remote) )
5
+ def strip_fields_for_differ_to_ignore(config)
6
+ deep_cloned_remote_config = Marshal.load( Marshal.dump(config) )
17
7
  if deep_cloned_remote_config.key?(:Pool)
18
8
  deep_cloned_remote_config[:Pool].each do |pool_entry|
19
9
  pool_entry.delete(:Operational)
@@ -0,0 +1,18 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+ class NatConfigurationDiffer < ConfigurationDiffer
4
+
5
+ def strip_fields_for_differ_to_ignore(config)
6
+ deep_cloned_config = Marshal.load( Marshal.dump(config) )
7
+ if deep_cloned_config.key?(:NatRule)
8
+ deep_cloned_config[:NatRule].each do |nat_rule|
9
+ nat_rule.delete(:Id)
10
+ end
11
+ end
12
+ deep_cloned_config
13
+ end
14
+
15
+ end
16
+ end
17
+
18
+ end
@@ -1,6 +1,6 @@
1
1
  module Vcloud
2
2
  module EdgeGateway
3
- VERSION = '0.2.2'
3
+ VERSION = '0.2.3'
4
4
  end
5
5
  end
6
6
 
@@ -4,7 +4,7 @@ module Vcloud
4
4
  class EdgeGatewayServices
5
5
 
6
6
  def initialize
7
- @config_loader = Vcloud::ConfigLoader.new
7
+ @config_loader = Vcloud::Core::ConfigLoader.new
8
8
  end
9
9
 
10
10
  def update(config_file = nil)
@@ -49,13 +49,6 @@ module Vcloud
49
49
 
50
50
  context "Check update is functional" do
51
51
 
52
- before(:all) do
53
- local_config = ConfigLoader.new.load_config(
54
- @initial_config_file,
55
- Vcloud::Schema::EDGE_GATEWAY_SERVICES
56
- )
57
- end
58
-
59
52
  it "should be starting our tests from an empty EdgeGateway" do
60
53
  remote_vcloud_config = @edge_gateway.vcloud_attributes[:Configuration][:EdgeGatewayServiceConfiguration]
61
54
  expect(remote_vcloud_config[:FirewallService][:FirewallRule].empty?).to be_true
@@ -65,7 +58,7 @@ module Vcloud
65
58
  end
66
59
 
67
60
  it "should only create one edgeGateway update task when updating the configuration" do
68
- start_time = DateTime.now()
61
+ start_time = Time.now.getutc
69
62
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
70
63
  EdgeGatewayServices.new.update(@initial_config_file)
71
64
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -81,7 +74,7 @@ module Vcloud
81
74
  end
82
75
 
83
76
  it "should not update the EdgeGateway again if the config hasn't changed" do
84
- start_time = DateTime.now()
77
+ start_time = Time.now.getutc
85
78
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
86
79
  EdgeGatewayServices.new.update(@initial_config_file)
87
80
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -89,7 +82,7 @@ module Vcloud
89
82
  end
90
83
 
91
84
  it "should only create one additional edgeGateway update task when adding the LoadBalancer config" do
92
- start_time = DateTime.now()
85
+ start_time = Time.now.getutc
93
86
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
94
87
  EdgeGatewayServices.new.update(@adding_load_balancer_config_file)
95
88
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -97,7 +90,7 @@ module Vcloud
97
90
  end
98
91
 
99
92
  it "should not update the EdgeGateway again if we reapply the 'adding load balancer' config" do
100
- start_time = DateTime.now()
93
+ start_time = Time.now.getutc
101
94
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
102
95
  EdgeGatewayServices.new.update(@adding_load_balancer_config_file)
103
96
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -147,12 +140,13 @@ module Vcloud
147
140
 
148
141
  def get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(timestamp)
149
142
  vcloud_time = timestamp.strftime('%FT%T.000Z')
150
- q = Query.new('task',
143
+ q = QueryRunner.new
144
+
145
+ q.run('task',
151
146
  :filter =>
152
147
  "name==networkConfigureEdgeGatewayServices;objectName==#{@edge_name};startDate=ge=#{vcloud_time}",
153
148
  :sortDesc => 'startDate',
154
149
  )
155
- q.get_all_results
156
150
  end
157
151
 
158
152
  end
@@ -41,20 +41,10 @@ module Vcloud
41
41
  @firewall_service = {}
42
42
  end
43
43
 
44
- context "Check input schema checking is working" do
45
-
46
- it "should raise exception if input yaml does not match with schema" do
47
- config_yaml = File.expand_path('data/incorrect_firewall_config.yaml', File.dirname(__FILE__))
48
- expect(Vcloud::EdgeGateway.logger).to receive(:fatal)
49
- expect { EdgeGatewayServices.new.update(config_yaml) }.to raise_error('Supplied configuration does not match supplied schema')
50
- end
51
-
52
- end
53
-
54
44
  context "Check update is functional" do
55
45
 
56
46
  before(:all) do
57
- local_config = ConfigLoader.new.load_config(@initial_firewall_config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES)
47
+ local_config = Core::ConfigLoader.new.load_config(@initial_firewall_config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES)
58
48
  @local_vcloud_config = EdgeGateway::ConfigurationGenerator::FirewallService.new.generate_fog_config(local_config[:firewall_service])
59
49
  end
60
50
 
@@ -94,7 +84,7 @@ module Vcloud
94
84
  it "should highlight a difference if local firewall config has been updated" do
95
85
  input_config_file = generate_input_config_file('firewall_config_updated_rule.yaml.erb', edge_gateway_erb_input)
96
86
 
97
- local_config = ConfigLoader.new.load_config(input_config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES)
87
+ local_config = Core::ConfigLoader.new.load_config(input_config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES)
98
88
  local_firewall_config = EdgeGateway::ConfigurationGenerator::FirewallService.new.generate_fog_config(local_config[:firewall_service])
99
89
 
100
90
  edge_gateway = Core::EdgeGateway.get_by_name local_config[:gateway]
@@ -44,7 +44,7 @@ module Vcloud
44
44
  context "Check update is functional" do
45
45
 
46
46
  before(:all) do
47
- local_config = ConfigLoader.new.load_config(
47
+ local_config = Core::ConfigLoader.new.load_config(
48
48
  @initial_load_balancer_config_file,
49
49
  Vcloud::Schema::EDGE_GATEWAY_SERVICES
50
50
  )
@@ -61,7 +61,7 @@ module Vcloud
61
61
  end
62
62
 
63
63
  it "should only make one EdgeGateway update task, to minimise EdgeGateway reload events" do
64
- start_time = DateTime.now()
64
+ start_time = Time.now.getutc
65
65
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
66
66
  EdgeGatewayServices.new.update(@initial_load_balancer_config_file)
67
67
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -190,12 +190,12 @@ module Vcloud
190
190
 
191
191
  def get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(timestamp)
192
192
  vcloud_time = timestamp.strftime('%FT%T.000Z')
193
- q = Query.new('task',
193
+ q = QueryRunner.new
194
+ q.run('task',
194
195
  :filter =>
195
196
  "name==networkConfigureEdgeGatewayServices;objectName==#{@edge_name};startDate=ge=#{vcloud_time}",
196
197
  :sortDesc => 'startDate',
197
198
  )
198
- q.get_all_results
199
199
  end
200
200
 
201
201
  end
@@ -49,7 +49,7 @@ module Vcloud
49
49
  context "Check update is functional" do
50
50
 
51
51
  before(:all) do
52
- local_config = ConfigLoader.new.load_config(
52
+ local_config = Core::ConfigLoader.new.load_config(
53
53
  @initial_nat_config_file, Vcloud::Schema::EDGE_GATEWAY_SERVICES
54
54
  )
55
55
  @local_vcloud_config = EdgeGateway::ConfigurationGenerator::NatService.new(
@@ -64,7 +64,7 @@ module Vcloud
64
64
  end
65
65
 
66
66
  it "should only make one EdgeGateway update task, to minimise EdgeGateway reload events" do
67
- start_time = DateTime.now()
67
+ start_time = Time.now.getutc
68
68
  task_list_before_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
69
69
  EdgeGatewayServices.new.update(@initial_nat_config_file)
70
70
  task_list_after_update = get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(start_time)
@@ -200,11 +200,11 @@ module Vcloud
200
200
 
201
201
  def get_all_edge_gateway_update_tasks_ordered_by_start_date_since_time(timestamp)
202
202
  vcloud_time = timestamp.strftime('%FT%T.000Z')
203
- q = Query.new('task',
203
+ q = QueryRunner.new
204
+ q.run('task',
204
205
  :filter => "name==networkConfigureEdgeGatewayServices;objectName==#{@edge_name};startDate=ge=#{vcloud_time}",
205
206
  :sortDesc => 'startDate',
206
207
  )
207
- q.get_all_results
208
208
  end
209
209
 
210
210
  end
@@ -18,9 +18,9 @@ require 'vcloud/edge_gateway'
18
18
  SimpleCov.at_exit do
19
19
  SimpleCov.result.format!
20
20
  # do not change the coverage percentage, instead add more unit tests to fix coverage failures.
21
- if SimpleCov.result.covered_percent < 60
21
+ if SimpleCov.result.covered_percent < 90
22
22
  print "ERROR::BAD_COVERAGE\n"
23
- print "Coverage is less than acceptable limit(71%). Please add more tests to improve the coverage"
23
+ print "Coverage is less than acceptable limit(90%). Please add more tests to improve the coverage\n"
24
24
  exit(1)
25
25
  end
26
26
  end
@@ -0,0 +1,132 @@
1
+ module Vcloud
2
+ module EdgeGateway
3
+
4
+ shared_examples "a configuration differ" do
5
+
6
+ let(:config_differ) { described_class }
7
+
8
+ it 'should return an empty array for two identical empty Hashes' do
9
+ local = { }
10
+ remote = { }
11
+ output = []
12
+ differ = config_differ.new(local, remote)
13
+ expect(differ.diff).to eq(output)
14
+ end
15
+
16
+ it 'should return an empty array for two identical simple Hashes' do
17
+ local = { testing: 'testing', one: 1, two: 'two', three: "3" }
18
+ remote = { testing: 'testing', one: 1, two: 'two', three: "3" }
19
+ output = []
20
+ differ = config_differ.new(local, remote)
21
+ expect(differ.diff).to eq(output)
22
+ end
23
+
24
+ it 'should return an empty array for two identical deep Hashes' do
25
+ local = { testing: 'testing', one: 1, deep: [
26
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
27
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
28
+ ]}
29
+ remote = { testing: 'testing', one: 1, deep: [
30
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
31
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
32
+ ]}
33
+ output = []
34
+ differ = config_differ.new(local, remote)
35
+ expect(differ.diff).to eq(output)
36
+ end
37
+
38
+ it 'should highlight a simple addition' do
39
+ local = { foo: '1' }
40
+ remote = { foo: '1', bar: '2' }
41
+ output = [["+", "bar", "2"]]
42
+ differ = config_differ.new(local, remote)
43
+ expect(differ.diff).to eq(output)
44
+ end
45
+
46
+ it 'should highlight a simple subtraction' do
47
+ local = { foo: '1', bar: '2' }
48
+ remote = { foo: '1' }
49
+ output = [["-", "bar", "2"]]
50
+ differ = config_differ.new(local, remote)
51
+ expect(differ.diff).to eq(output)
52
+ end
53
+
54
+ it 'should highlight a deep addition' do
55
+ local = { testing: 'testing', one: 1, deep: [
56
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
57
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
58
+ ]}
59
+ remote = { testing: 'testing', one: 1, deep: [
60
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5, 6 ] },
61
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
62
+ ]}
63
+ output = [["+", "deep[0].deeper[5]", 6]]
64
+ differ = config_differ.new(local, remote)
65
+ expect(differ.diff).to eq(output)
66
+ end
67
+
68
+ it 'should highlight a deep subtraction' do
69
+ local = { testing: 'testing', one: 1, deep: [
70
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
71
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
72
+ ]}
73
+ remote = { testing: 'testing', one: 1, deep: [
74
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
75
+ { baz: 'bop', deeper: [ 6, 5, 3, 2 ] },
76
+ ]}
77
+ output = [["-", "deep[1].deeper[2]", 4]]
78
+ differ = config_differ.new(local, remote)
79
+ expect(differ.diff).to eq(output)
80
+ end
81
+
82
+ it 'should return an empty array when hash params are reordered' do
83
+ local = { one: 1, testing: 'testing', deep: [
84
+ { deeper: [ 1, 2, 3, 4, 5 ], foo: 'bar' },
85
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
86
+ ]}
87
+ remote = { testing: 'testing', one: 1, deep: [
88
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
89
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
90
+ ]}
91
+ output = []
92
+ differ = config_differ.new(local, remote)
93
+ expect(differ.diff).to eq(output)
94
+ end
95
+
96
+ it 'should highlight when array elements are reordered' do
97
+ local = { testing: 'testing', one: 1, deep: [
98
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
99
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
100
+ ]}
101
+ remote = { testing: 'testing', one: 1, deep: [
102
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
103
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
104
+ ]}
105
+ output = [
106
+ ["+", "deep[0]", {:foo=>"bar", :deeper=>[1, 2, 3, 4, 5]}],
107
+ ["-", "deep[2]", {:foo=>"bar", :deeper=>[1, 2, 3, 4, 5]}],
108
+ ]
109
+ differ = config_differ.new(local, remote)
110
+ expect(differ.diff).to eq(output)
111
+ end
112
+
113
+ it 'should highlight when deep array elements are reordered' do
114
+ local = { testing: 'testing', one: 1, deep: [
115
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
116
+ { baz: 'bop', deeper: [ 5, 6, 4, 3, 2 ] },
117
+ ]}
118
+ remote = { testing: 'testing', one: 1, deep: [
119
+ { foo: 'bar', deeper: [ 1, 2, 3, 4, 5 ] },
120
+ { baz: 'bop', deeper: [ 6, 5, 4, 3, 2 ] },
121
+ ]}
122
+ output = [
123
+ ["+", "deep[1].deeper[0]", 6],
124
+ ["-", "deep[1].deeper[2]", 6]
125
+ ]
126
+ differ = config_differ.new(local, remote)
127
+ expect(differ.diff).to eq(output)
128
+ end
129
+ end
130
+
131
+ end
132
+ end