package pijul
import (
_ "embed"
"reflect"
"testing"
"time"
"github.com/davecgh/go-spew/spew"
)
var CB7A3P []byte
var DSPWN6 []byte
var MRE2H2 []byte
var changeTestCases = []struct {
hash string
data []byte
parsed Change
text string
}{
{
hash: "CB7A3PP3XC6JY3QYUUNB4WCXGNFJMHTTH54MBAWBUVQL7TTHWBBQC",
data: CB7A3P,
parsed: Change{
Version: 6,
Message: "Say hello",
Description: "a trivial change",
Timestamp: time.Date(2023, 3, 27, 18, 51, 58, 26097601, time.UTC),
Authors: []map[string]string{
{
"key": "BCEXYuKWaQ96btsk8UyBZWHLjn1Brhykv8tuZGPRjzFn",
},
},
Dependencies: []Hash{Hash{0xe7, 0x82, 0xb1, 0xd7, 0xe4, 0x17, 0x64, 0xe4, 0xfe, 0x45, 0x2d, 0x6f, 0x24, 0x22, 0x40, 0x26, 0x16, 0x12, 0xb7, 0xf, 0x42, 0x70, 0xd9, 0xac, 0xd8, 0x4e, 0x5a, 0x82, 0xea, 0x85, 0xab, 0x57}},
ExtraKnown: []Hash{},
Metadata: []byte{},
Changes: []Hunk{
FileAdd{
AddName: NewVertex{
UpContext: []Position{
Position{
Change: OptionalHash{true, Hash{0xe7, 0x82, 0xb1, 0xd7, 0xe4, 0x17, 0x64, 0xe4, 0xfe, 0x45, 0x2d, 0x6f, 0x24, 0x22, 0x40, 0x26, 0x16, 0x12, 0xb7, 0x0f, 0x42, 0x70, 0xd9, 0xac, 0xd8, 0x4e, 0x5a, 0x82, 0xea, 0x85, 0xab, 0x57}},
Pos: 0x1,
},
},
DownContext: []Position{},
Flag: 0x11,
Start: 0x0,
End: 0x1d,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0x0,
},
},
AddInode: NewVertex{
UpContext: []Position{
Position{
Change: OptionalHash{},
Pos: 0x1d,
},
},
DownContext: []Position{},
Flag: 0x11,
Start: 0x1e,
End: 0x1e,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0x0,
},
},
Contents: NewVertex{
UpContext: []Position{
Position{
Change: OptionalHash{},
Pos: 0x1e,
},
},
DownContext: []Position{},
Flag: 0x1,
Start: 0x1f,
End: 0x2c,
Inode: Position{
Change: OptionalHash{},
Pos: 0x1e,
},
},
Path: "hello",
Encoding: "UTF-8",
},
},
ContentsHash: Hash{0x9e, 0xb3, 0xf7, 0x5c, 0x66, 0x9f, 0x18, 0xec, 0x4f, 0xf7, 0x30, 0x51, 0x42, 0xfe, 0x79, 0xbd, 0x52, 0x87, 0x24, 0x1, 0x1a, 0xc5, 0x77, 0xe8, 0xf9, 0x5b, 0x14, 0xd9, 0xee, 0xf7, 0x21, 0x48},
Unhashed: map[string]any{
"signature": "4cKLG1A2wd3pp6hBMaceFCGo8ADhUaDNz31MJeZxNFYnBf8yPepXfgor9o78y88ComC3b1YzDccucDbPbez9Ppxe",
},
Contents: []byte{
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x01,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x00, 0x00, 0x68,
0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00,
},
},
},
{
hash: "DSPWN6DOSXQ3IIPW2JNOLFP32C7SQTSQZ7BBSEGA4UWNXQXNMS6AC",
data: DSPWN6,
parsed: Change{
Version: 6,
Message: "",
Timestamp: time.Date(2023, 3, 29, 23, 24, 28, 233348937, time.UTC),
Authors: []map[string]string{},
Dependencies: []Hash{},
ExtraKnown: []Hash{},
Metadata: []byte{},
Changes: []Hunk{
AddRoot{
Name: NewVertex{
UpContext: []Position{
{
Change: OptionalHash{true, Hash{}},
Pos: 0,
},
},
DownContext: []Position{},
Flag: 17,
Start: 0,
End: 0,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0,
},
},
Inode: NewVertex{
UpContext: []Position{
{
Change: OptionalHash{},
Pos: 0,
},
},
DownContext: []Position{},
Flag: 17,
Start: 1,
End: 1,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0,
},
},
},
},
ContentsHash: mustHashFromBase32("QXZAPGWPXKVFMHB5UIIYKF4K2STXSWH3RPLXVTR5WR6HKSERFVOAC"),
Contents: []byte{
0xfa, 0x7b, 0xfe, 0x96, 0x61, 0x6e, 0x0a, 0xa1, 0x6b, 0x40, 0x73, 0xa6, 0x99, 0xf8, 0xbb, 0x8c,
0x15, 0x35, 0xc9, 0x3f, 0x6f, 0xfc, 0x8f, 0x4b, 0x72, 0xd8, 0xa9, 0x1d, 0xd4, 0xde, 0x7f, 0x86,
},
},
text: `message = ''
timestamp = '2023-03-29T23:24:28.233348937Z'
authors = []
# Hunks
1. Root add
up 1.0, new 0:0`,
},
{
hash: "MRE2H23UNRCHMZIKISVB4T7DTDDVVK7DCCSLFEMXOXLLQNQVELGAC",
data: MRE2H2,
parsed: Change{
Version: 6,
Message: "original",
Description: "example from https://jneem.github.io/merging/",
Timestamp: time.Date(2023, 3, 29, 23, 34, 47, 120245376, time.UTC),
Authors: []map[string]string{
{"key": "BCEXYuKWaQ96btsk8UyBZWHLjn1Brhykv8tuZGPRjzFn"},
},
Dependencies: []Hash{mustHashFromBase32("DSPWN6DOSXQ3IIPW2JNOLFP32C7SQTSQZ7BBSEGA4UWNXQXNMS6AC")},
ExtraKnown: []Hash{},
Metadata: []byte{},
Changes: []Hunk{
FileAdd{
AddName: NewVertex{
UpContext: []Position{
{
Change: OptionalHash{true, mustHashFromBase32("DSPWN6DOSXQ3IIPW2JNOLFP32C7SQTSQZ7BBSEGA4UWNXQXNMS6AC")},
Pos: 1,
},
},
DownContext: []Position{},
Flag: 17,
Start: 0,
End: 32,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0,
},
},
AddInode: NewVertex{
UpContext: []Position{
{
Change: OptionalHash{},
Pos: 32,
},
},
DownContext: []Position{},
Flag: 17,
Start: 33,
End: 33,
Inode: Position{
Change: OptionalHash{true, Hash{}},
Pos: 0,
},
},
Contents: NewVertex{
UpContext: []Position{
{
Change: OptionalHash{},
Pos: 33,
},
},
DownContext: []Position{},
Flag: 1,
Start: 34,
End: 47,
Inode: Position{
Change: OptionalHash{},
Pos: 33,
},
},
Path: "todo.txt",
Encoding: "UTF-8",
},
},
ContentsHash: mustHashFromBase32("JQF7WZBVPIA2Z4VKCKGLBQFNX77WJUKI7Z6CFFD4A56URAKVFYPAC"),
Unhashed: map[string]any{
"signature": "3MQQMzBdjRGQCZ7RcvMoAFA3BQsU4EFEU15R34oNKsYmsmqcrBt6qfMesq5B5akKBoQtm5yhpjCpcnMxbTWHgUxJ",
},
Contents: []byte{
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x74,
0x78, 0x74, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x54, 0x46, 0x2d, 0x38,
0x00, 0x00, 0x74, 0x6f, 0x2d, 0x64, 0x6f, 0x0a, 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x0a, 0x00,
},
},
text: `message = 'original'
description = 'example from https://jneem.github.io/merging/'
timestamp = '2023-03-29T23:34:47.120245376Z'
[[authors]]
key = 'BCEXYuKWaQ96btsk8UyBZWHLjn1Brhykv8tuZGPRjzFn'
# Dependencies
[2] DSPWN6DOSXQ3IIPW2JNOLFP32C7SQTSQZ7BBSEGA4UWNXQXNMS6AC #
# Hunks
1. File addition: "todo.txt" in "" "UTF-8"
up 2.1, new 0:32
+ to-do
+ * work`,
},
}
func TestDeserializeChange(t *testing.T) {
for _, testCase := range changeTestCases {
c, err := DeserializeChange(testCase.data)
if err != nil {
t.Errorf("%s: deserialization error: %v", testCase.hash, err)
continue
}
if !reflect.DeepEqual(c, testCase.parsed) {
t.Errorf("%s: got %s, want %s", testCase.hash, spew.Sdump(c), spew.Sdump(testCase.parsed))
}
}
}
func TestHashBase32(t *testing.T) {
hs := "CB7A3PP3XC6JY3QYUUNB4WCXGNFJMHTTH54MBAWBUVQL7TTHWBBQC"
hash, err := HashFromBase32(hs)
if err != nil {
t.Fatalf("error parsing hash: %v", err)
}
if hash.String() != hs {
t.Fatalf("got %s, want %s", hash.String(), hs)
}
}