- 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
107 lines
4.0 KiB
Ruby
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
|