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
This commit is contained in:
co-authored by
Claude Fable 5
parent
e0cd0f0d7a
commit
6dd57e84f1
@@ -0,0 +1,106 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user