diff options
Diffstat (limited to 'tooling/lib/tooling/test_map_packer.rb')
-rw-r--r-- | tooling/lib/tooling/test_map_packer.rb | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tooling/lib/tooling/test_map_packer.rb b/tooling/lib/tooling/test_map_packer.rb new file mode 100644 index 00000000000..520d69610eb --- /dev/null +++ b/tooling/lib/tooling/test_map_packer.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Tooling + class TestMapPacker + SEPARATOR = '/'.freeze + MARKER = 1 + + def pack(map) + map.transform_values(&method(:create_tree_from_tests)) + end + + def unpack(compact_map) + compact_map.transform_values(&method(:retrieve_tests_from_tree)) + end + + private + + def create_tree_from_tests(tests) + tests.inject({}) do |tree, test| + segments = test.split(SEPARATOR) + branch = create_branch_from_segments(segments) + deep_merge(tree, branch) + end + end + + def create_branch_from_segments(segments) + segments.reverse.inject(MARKER) { |node, parent| { parent => node } } + end + + def deep_merge(hash, other) + hash.merge(other) do |_, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + deep_merge(this_val, other_val) + else + other_val + end + end + end + + def retrieve_tests_from_tree(tree) + traverse(tree).inject([]) do |tests, test| + tests << test + end + end + + def traverse(tree, segments = [], &block) + return to_enum(__method__, tree, segments) unless block_given? + + if tree == MARKER + return yield segments.join(SEPARATOR) + end + + tree.each do |key, value| + traverse(value, segments + [key], &block) + end + end + end +end |