134 lines
6.4 KiB
Ruby
134 lines
6.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "test_helper"
|
|
|
|
class GeneratorTest < Minitest::Test
|
|
def test_one_piece_multicolor_package
|
|
Dir.mktmpdir do |dir|
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
config = MoonModel::Config.new(
|
|
"size" => { "value" => 40 }, "resolution" => { "longitude_segments" => 24 },
|
|
"palette" => [{ "name" => "dark", "hex" => "#222222" }, { "name" => "light", "hex" => "#DDDDDD" }],
|
|
"grid" => { "enabled" => true, "color_name" => "light" }, "output" => { "name" => "test" }
|
|
)
|
|
result = MoonModel::Generator.new(config, data_set: data, output_dir: File.join(dir, "out")).generate
|
|
path = File.join(result[:output_dir], "moon.3mf")
|
|
assert File.file?(path)
|
|
Zip::File.open(path) do |zip|
|
|
model = zip.read("3D/3dmodel.model")
|
|
assert_includes model, "<basematerials"
|
|
assert_includes model, "displaycolor=\"#222222\""
|
|
assert_includes model, "<components>"
|
|
end
|
|
assert File.file?(File.join(result[:output_dir], "manifest.md"))
|
|
manifest = File.read(File.join(result[:output_dir], "manifest.md"))
|
|
assembly = File.read(File.join(result[:output_dir], "ASSEMBLY.md"))
|
|
assert_includes manifest, "Interior: solid slicer volume"
|
|
assert_includes assembly, "no internal cavity supports are required"
|
|
assert_in_delta 40.0, result[:statistics]["final_envelope_mm"], 0.01
|
|
end
|
|
end
|
|
|
|
def test_segmented_box_outputs_parts_keys_and_stand
|
|
Dir.mktmpdir do |dir|
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
config = MoonModel::Config.new("purpose" => "box", "size" => { "value" => 50 },
|
|
"stand" => { "enabled" => true },
|
|
"resolution" => { "longitude_segments" => 24 })
|
|
result = MoonModel::Generator.new(config, data_set: data, output_dir: File.join(dir, "out")).generate
|
|
assert_equal 8, Dir[File.join(result[:output_dir], "north_*.3mf")].length + Dir[File.join(result[:output_dir], "south_*.3mf")].length
|
|
assert File.file?(File.join(result[:output_dir], "assembly_keys.3mf"))
|
|
assert File.file?(File.join(result[:output_dir], "orbital_triskelion_stand.3mf"))
|
|
manifest = File.read(File.join(result[:output_dir], "manifest.md"))
|
|
assert_includes manifest, "Stand style: Orbital triskelion"
|
|
assert_includes manifest, "terrain_envelope_v3 (rotation independent)"
|
|
assert_includes manifest, "one connected solid; six branches support three concave pads"
|
|
assert_includes manifest, "local supports may be needed"
|
|
assert_includes manifest, "Guaranteed Moon clearance above hub/base: 10.00 mm"
|
|
assert_includes manifest, "Stand dimensions:"
|
|
end
|
|
end
|
|
|
|
def test_invalid_preflight_does_not_create_output_directory
|
|
Dir.mktmpdir do |dir|
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
config = MoonModel::Config.new("size" => { "value" => 40, "meaning" => "datum" },
|
|
"vertical_exaggeration" => 100_000,
|
|
"resolution" => { "longitude_segments" => 24 })
|
|
output = File.join(dir, "out")
|
|
|
|
assert_raises(ArgumentError) { MoonModel::Generator.new(config, data_set: data, output_dir: output).generate }
|
|
refute Dir.exist?(output)
|
|
end
|
|
end
|
|
|
|
def test_revision_atomically_replaces_obsolete_files
|
|
Dir.mktmpdir do |dir|
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
output = File.join(dir, "named_moon")
|
|
common = { "size" => { "value" => 40 }, "resolution" => { "longitude_segments" => 24 },
|
|
"output" => { "name" => "Named Moon" } }
|
|
MoonModel::Generator.new(MoonModel::Config.new(common), data_set: data, output_dir: output).generate
|
|
assert File.file?(File.join(output, "moon.3mf"))
|
|
|
|
revised = MoonModel::Config.new(common.merge("assembly" => "eight_piece"))
|
|
MoonModel::Generator.new(revised, data_set: data, output_dir: output).generate
|
|
|
|
refute File.exist?(File.join(output, "moon.3mf"))
|
|
assert File.file?(File.join(output, "north_1.3mf"))
|
|
assert MoonModel::Generator.generated_directory?(output)
|
|
end
|
|
end
|
|
|
|
def test_refuses_to_replace_unrelated_directory
|
|
Dir.mktmpdir do |dir|
|
|
output = File.join(dir, "not_a_model")
|
|
Dir.mkdir(output)
|
|
File.write(File.join(output, "keep.txt"), "important")
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
config = MoonModel::Config.new("size" => { "value" => 40 },
|
|
"resolution" => { "longitude_segments" => 24 })
|
|
|
|
assert_raises(ArgumentError) { MoonModel::Generator.new(config, data_set: data, output_dir: output).generate }
|
|
assert_equal "important", File.read(File.join(output, "keep.txt"))
|
|
end
|
|
end
|
|
|
|
def test_failed_atomic_install_restores_previous_model
|
|
Dir.mktmpdir do |dir|
|
|
data = MoonModel::DataSet.new(make_data(File.join(dir, "data.gz")))
|
|
output = File.join(dir, "recoverable")
|
|
common = { "size" => { "value" => 40 }, "resolution" => { "longitude_segments" => 24 },
|
|
"output" => { "name" => "Recoverable" } }
|
|
MoonModel::Generator.new(MoonModel::Config.new(common), data_set: data, output_dir: output).generate
|
|
original = File.binread(File.join(output, "moon.3mf"))
|
|
failing_class = Class.new(MoonModel::Generator) do
|
|
private
|
|
|
|
def rename_path(from, to)
|
|
@rename_count = @rename_count.to_i + 1
|
|
raise IOError, "simulated install failure" if @rename_count == 2
|
|
super
|
|
end
|
|
end
|
|
|
|
error = assert_raises(IOError) do
|
|
failing_class.new(MoonModel::Config.new(common.merge("assembly" => "eight_piece")),
|
|
data_set: data, output_dir: output).generate
|
|
end
|
|
assert_equal "simulated install failure", error.message
|
|
assert_equal original, File.binread(File.join(output, "moon.3mf"))
|
|
assert_empty Dir[File.join(dir, ".recoverable.*")]
|
|
end
|
|
end
|
|
|
|
def test_safe_model_name_and_default_build_directory
|
|
config = MoonModel::Config.new("output" => { "name" => "My 8-inch Moon!" })
|
|
generator = MoonModel::Generator.new(config)
|
|
|
|
assert_equal "My_8-inch_Moon", MoonModel::Generator.safe_name("My 8-inch Moon!")
|
|
assert_equal File.expand_path("../build/My_8-inch_Moon", __dir__), generator.output_dir
|
|
assert_raises(ArgumentError) { MoonModel::Generator.safe_name("...") }
|
|
end
|
|
end
|