require_relative "test_helper" require "open3" require "json" class CliTest < Minitest::Test include AdrTestHelpers ADR_NEW = File.join(PLUGIN_ROOT, "bin", "adr-new") ADR_INIT = File.join(PLUGIN_ROOT, "bin", "adr-init") def run_new(root, input) out, err, status = Open3.capture3("ruby", ADR_NEW, "--root", root, stdin_data: JSON.generate(input)) [out.strip, err, status] end def run_init(root) Open3.capture3("ruby", ADR_INIT, "--root", root) end def test_init_creates_dir_and_index_and_clears_suppress Dir.mktmpdir do |root| FileUtils.mkdir_p(File.join(root, ".os-adr")) File.write(File.join(root, ".os-adr", "suppress"), "") _out, _err, status = run_init(root) assert status.success? repo = Adr::Repository.new(root: root) assert repo.exists? refute File.exist?(File.join(root, ".os-adr", "suppress")) end end def test_init_is_idempotent_and_preserves_existing_adrs with_project("0001-a.md" => sample_adr) do |root| _out, _err, status = run_init(root) assert status.success? assert_includes File.read(Adr::Repository.new(root: root).index_path), "0001" end end def test_new_creates_templated_numbered_indexed_adr with_project("0001-a.md" => sample_adr(id: "0001")) do |root| out, err, status = run_new(root, title: "Use Postgres", context: "We need a DB.", decision: "Postgres.", consequences: "Ops.", alternatives: "SQLite.", affected_paths: ["db/"], affected_components: ["storage"]) assert status.success?, err assert out.end_with?("0002-use-postgres.md") record = Adr::Record.parse(File.read(out)) assert_equal "0002", record.id assert_equal "Accepted", record.status assert_equal "Use Postgres", record.title assert_equal ["db/"], record.frontmatter["affected-paths"] Adr::Record::SECTION_ORDER.each { |s| assert record.sections.key?(s), "missing section #{s}" } assert_includes File.read(Adr::Repository.new(root: root).index_path), "[Use Postgres](0002-use-postgres.md)" end end def test_new_supersession_is_mechanical with_project("0004-old-way.md" => sample_adr(id: "0004", title: "Old way")) do |root| out, err, status = run_new(root, title: "New way", supersedes: "0004") assert status.success?, err new_record = Adr::Record.parse(File.read(out)) assert_equal "0004", new_record.frontmatter["supersedes"] old = Adr::Repository.new(root: root).find("0004") assert_equal new_record.id, old.record.frontmatter["superseded-by"] assert_equal "Superseded", old.record.status index = File.read(Adr::Repository.new(root: root).index_path) assert_includes index, "| Superseded |" assert_includes index, "| Accepted |" end end def test_new_requires_title with_project do |root| _out, err, status = run_new(root, {}) refute status.success? assert_includes err, "title" end end def test_new_fails_cleanly_without_init Dir.mktmpdir do |root| _out, err, status = run_new(root, title: "X") refute status.success? assert_includes err, "adr-init" end end end