TrueChartsClone/tests/test_helper.rb

147 lines
3.1 KiB
Ruby

# frozen_string_literal: true
require 'json'
require 'yaml'
require 'open3'
require 'minitest-implicit-subject'
require "minitest/reporters"
require 'minitest/autorun'
require 'minitest/pride'
class HelmCompileError < StandardError
end
class HelmDepsError < StandardError
end
class Chart
attr_reader :name, :path, :values
def initialize(chart)
@name = chart.split('/').last
@path = File.expand_path(chart)
@values = default_values
update_deps!
end
def update_deps!
command = "helm dep update '#{path}'"
stdout, stderr, status = Open3.capture3(command)
raise HelmDepsError, stderr if status != 0
end
def reset!
@values = default_values
@parsed_resources = nil
end
def value(value)
values.merge!(value)
end
def configure_custom_name(name)
@name = name
end
def execute_helm_template!
file = Tempfile.new(name)
file.write(JSON.parse(values.to_json).to_yaml)
file.close
begin
command = "helm template '#{name}' '#{path}' --namespace='default' --values='#{file.path}'"
stdout, stderr, status = Open3.capture3(command)
raise HelmCompileError, stderr if status != 0
stdout
ensure
file.unlink
end
end
def parsed_resources
@parsed_resources ||= begin
output = execute_helm_template!
puts output if ENV.fetch('DEBUG', 'false') == 'true'
YAML.load_stream(output)
end
end
def resources(matcher = nil)
return parsed_resources unless matcher
parsed_resources.select do |r|
r >= Hash[matcher.map { |k, v| [k.to_s, v] }]
end
end
def default_values
{
}
end
end
class ExtendedMinitest < Minitest::Test
extend MiniTest::Spec::DSL
end
class ChartTest < ExtendedMinitest
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
before do
chart.reset!
end
def chart
self.class.class_variable_get('@@chart')
end
def resource(name)
chart.resources(kind: name).first
end
end
class Minitest::Result
def name
test_name = defined?(@name) ? @name : super
test_name.to_s.gsub /\Atest_\d{4,}_/, ""
end
end
class ::Hash
def deep_merge_override(second)
merger = proc do |key, original, override|
if original.instance_of?(Hash) && override.instance_of?(Hash)
original.merge(override, &merger)
else
if original.instance_of?(Array) && override.instance_of?(Array)
# if the lengths are different, prefer the override
if original.length != override.length
override
else
# if the first element in the override's Array is a Hash, then we assume they all are
if override[0].instance_of?(Hash)
original.map.with_index do |v, i|
# deep merge everything between the two arrays
original[i].merge(override[i], &merger)
end
else
# if we don't have a Hash in the override,
# override the whole array with our new one
override
end
end
else
override
end
end
end
self.merge(second.to_h, &merger)
end
end