Initial parametric Feather case generator
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "test_helper"
|
||||
|
||||
class PackageBuilderTest < Minitest::Test
|
||||
def test_builds_self_contained_package_and_preserves_history
|
||||
Dir.mktmpdir do |directory|
|
||||
root = Pathname(directory)
|
||||
tools = create_fake_tools(root)
|
||||
model = root.join("model.scad")
|
||||
renderer = root.join("renderer.py")
|
||||
File.write(model, "cube([1,1,1]);\n")
|
||||
File.write(renderer, "# test renderer\n")
|
||||
config = FeatherCaseWizard::Config.create(name: "OLED Demo", slug: "oled-demo")
|
||||
config.parameters["top_profile"] = "oled128x64"
|
||||
config.outputs["formats"] = %w[3mf stl]
|
||||
config.outputs["coupons"] = %w[fit_coupon]
|
||||
|
||||
destination = build(config, root.join("cases"), tools, model, renderer)
|
||||
|
||||
assert destination.join("case.yml").file?
|
||||
assert destination.join("parameters.json").file?
|
||||
assert destination.join("build.rb").executable?
|
||||
%w[body lid buttons fit_coupon].each do |part|
|
||||
assert destination.join("exports/stl/#{part}.stl").file?
|
||||
assert destination.join("exports/3mf/#{part}.3mf").file?
|
||||
assert destination.join("previews/#{part}_iso.png").file?
|
||||
end
|
||||
%w[iso front back left right top].each do |view|
|
||||
assert destination.join("previews/assembly_#{view}.png").file?
|
||||
end
|
||||
|
||||
config.parameters["button_reset"] = true
|
||||
build(config, root.join("cases"), tools, model, renderer)
|
||||
assert_equal 1, Dir.glob(destination.join("history/case-*.yml")).length
|
||||
end
|
||||
end
|
||||
|
||||
def test_failed_build_leaves_existing_package_untouched
|
||||
Dir.mktmpdir do |directory|
|
||||
root = Pathname(directory)
|
||||
destination = root.join("cases/demo")
|
||||
FileUtils.mkdir_p(destination)
|
||||
File.write(destination.join("sentinel"), "keep")
|
||||
model = root.join("model.scad")
|
||||
renderer = root.join("renderer.py")
|
||||
File.write(model, "cube(1);\n")
|
||||
File.write(renderer, "# renderer\n")
|
||||
failing = Class.new do
|
||||
attr_reader :openscad, :blender
|
||||
def initialize
|
||||
@openscad = @blender = "/fake"
|
||||
end
|
||||
def check! = self
|
||||
def run!(*)
|
||||
raise FeatherCaseWizard::ToolError, "planned failure"
|
||||
end
|
||||
end.new
|
||||
config = FeatherCaseWizard::Config.create(name: "Demo", slug: "demo")
|
||||
|
||||
assert_raises(FeatherCaseWizard::ToolError) do
|
||||
FeatherCaseWizard::PackageBuilder.new(
|
||||
config, root: root.join("cases"), toolchain: failing,
|
||||
model_source: model, renderer_source: renderer
|
||||
).build!
|
||||
end
|
||||
assert_equal "keep", destination.join("sentinel").read
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build(config, root, tools, model, renderer)
|
||||
FeatherCaseWizard::PackageBuilder.new(
|
||||
config, root: root, toolchain: tools,
|
||||
model_source: model, renderer_source: renderer
|
||||
).build!
|
||||
end
|
||||
|
||||
def create_fake_tools(root)
|
||||
bin = root.join("bin")
|
||||
FileUtils.mkdir_p(bin)
|
||||
openscad = bin.join("openscad")
|
||||
blender = bin.join("blender")
|
||||
File.write(openscad, <<~RUBY)
|
||||
#!/usr/bin/env ruby
|
||||
output = ARGV[ARGV.index("-o") + 1]
|
||||
require "fileutils"
|
||||
FileUtils.mkdir_p(File.dirname(output))
|
||||
File.binwrite(output, "mesh")
|
||||
RUBY
|
||||
File.write(blender, <<~RUBY)
|
||||
#!/usr/bin/env ruby
|
||||
require "fileutils"
|
||||
args = ARGV[(ARGV.index("--") + 1)..]
|
||||
_mesh, output, basename, selected = args
|
||||
views = selected ? selected.split(",") : %w[iso front back left right top]
|
||||
FileUtils.mkdir_p(output)
|
||||
views.each { |view| File.binwrite(File.join(output, "\#{basename}_\#{view}.png"), "png") }
|
||||
RUBY
|
||||
FileUtils.chmod(0o755, [openscad, blender])
|
||||
FeatherCaseWizard::Toolchain.new(
|
||||
env: {"PATH" => bin.to_s, "OPENSCAD" => openscad.to_s, "BLENDER" => blender.to_s}
|
||||
)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user