Files
Dan MilneandClaude Fable 5 6dd57e84f1 Version 0.3.0: resolver/merge/cache refactor, signing design notes
- Split the monolith into package/provider/fetch/merge/cache modules with
  the Resolver deciding install/adopt/update/merge/conflict outcomes
- Three-way merges via git merge-file/diff3 against a content-addressed
  merge-base cache; conflicts go to a .picopackage-merge sibling
- Tests for package, provider, resolver, merge, and cache
- notes.md: update UX and signing design — diff-by-default, SSH signature
  identity pinning (TOFU), key changes as a hard stop, exit-code contract
- Add CLAUDE.md; remove the pre-refactor exe/pppkg monolith and scratch files

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EiyJC73Mz8xZyCTvCEY8qn
2026-08-13 21:18:19 +10:00

107 lines
4.0 KiB
Ruby

# frozen_string_literal: true
require "test_helper"
class TestPackage < Minitest::Test
include PicopackageTest
BARE = "def hello\n :world\nend\n"
def test_it_has_a_version_number
refute_nil ::Picopackage::VERSION
end
def test_a_bare_file_is_bare
assert Picopackage::Package.new(content: BARE).bare?
end
def test_a_generated_package_parses_back_as_a_package
package = Picopackage::Package.new(content: BARE).init_metadata(filename: "hello.rb")
round_tripped = Picopackage::Package.new(content: package.generate_package)
refute_predicate round_tripped, :bare?
assert_equal "hello.rb", round_tripped.filename
end
def test_reads_metadata_from_a_packaged_file
package = Picopackage::Package.from_file("test/files/uniquify_array_packaged.rb")
assert_equal "uniquify_array.rb", package.filename
assert_equal "https://api.github.com/gists/525ac4177964549ee2f2ca7febd03eea", package.url
end
# This was the bug that made every file look locally modified: the checksum
# written into a package hashed the un-normalised payload while verification
# hashed the normalised one, so nothing ever verified against itself.
def test_a_freshly_packaged_file_verifies_against_its_own_checksum
package = Picopackage::Package.new(content: BARE).init_metadata(filename: "hello.rb")
written = Picopackage::Package.new(content: package.generate_package)
assert written.verify_payload, "a package should satisfy its own checksum"
refute_predicate written, :modified?
end
def test_payload_digest_is_stable_across_packaging
bare = Picopackage::Package.new(content: BARE)
packaged = Picopackage::Package.new(
content: Picopackage::Package.new(content: BARE).init_metadata(filename: "hello.rb").generate_package
)
assert_equal bare.payload_digest, packaged.payload_digest,
"adding a metadata block must not change the payload digest"
end
def test_editing_a_payload_is_detected
packaged = Picopackage::Package.new(content: BARE).init_metadata(filename: "hello.rb").generate_package
edited = Picopackage::Package.new(content: packaged.sub(":world", ":everyone"))
assert_predicate edited, :modified?
end
def test_unmodelled_metadata_keys_survive_a_rewrite
content = <<~RUBY
code_here
# @PICOPACKAGE_START
# ---
# filename: thing.rb
# licence: MIT
# test_url: https://example.com/thing_test.rb
# @PICOPACKAGE_END
RUBY
package = Picopackage::Package.new(content: content)
assert_equal "MIT", package.metadata.extra["licence"]
rewritten = Picopackage::Package.new(content: package.generate_package)
assert_equal "MIT", rewritten.metadata.extra["licence"]
assert_equal "https://example.com/thing_test.rb", rewritten.metadata.extra["test_url"]
end
# A checksum is derived, never preserved. An author who edits a packaged file
# by hand and re-runs the tool must get a block describing what is now there,
# not the value that happened to already be sitting in it.
def test_a_stale_recorded_checksum_is_corrected_on_write
content = "code\n\n# @PICOPACKAGE_START\n# ---\n# filename: thing.rb\n" \
"# payload_checksum: sha256:#{"de" * 32}\n# @PICOPACKAGE_END\n"
stale = Picopackage::Package.new(content: content)
refute stale.verify_payload, "precondition: the recorded checksum is wrong"
rewritten = Picopackage::Package.new(content: stale.generate_package)
assert rewritten.verify_payload
refute_predicate rewritten, :modified?
end
def test_a_block_of_only_unmodelled_keys_is_not_treated_as_bare
content = "code\n\n# @PICOPACKAGE_START\n# ---\n# licence: MIT\n# @PICOPACKAGE_END\n"
refute_predicate Picopackage::Package.new(content: content), :bare?,
"a block we don't fully understand is still a block"
end
def test_malformed_front_matter_does_not_raise
package = Picopackage::Package.from_file("test/files/broken_front_matter_1.rb")
refute_nil package
assert_predicate package.metadata, :empty?
end
end