package delivery import ( "strings" "testing" ) // The named paths' git objects travel beside a module's other new-form inputs (novox/hq ADR 0499 clauses 2 and 3): in // the forge bridge's messages (Forge.Paths), in the merge preview (PreviewModule.Paths) and in what the indexer keeps // (KeptInputs2.Paths), so a computation from kept inputs gives the merge's value. Each is read as absent by an older // reader, and an older value, without them, still decodes. func TestTheNamedPathsObjectsRoundTripBesideTheOtherInputs(t *testing.T) { manifest := sha256Of(`{"module":"mesh-sdk"}`) paths := map[string]string{"src": strings.Repeat("a", 40), "package.json": strings.Repeat("b", 40)} tree, err := NamedTree(manifest, paths) if err != nil { t.Fatal(err) } m := Module{FP2: SourcePrefix2 + strings.Repeat("1", 64), Manifest: manifest, Repository: "novox/mesh-sdk", Commit: strings.Repeat("c", 40), Inputs2: &KeptInputs2{Tree: tree, Paths: paths}} m.FP = SourcePrefix + strings.Repeat("0", 64) data, err := EncodeModule(m) if err != nil { t.Fatal(err) } if !strings.Contains(string(data), `"paths":{`) { t.Fatalf("the kept inputs carry no paths: %s", data) } back, err := DecodeModule(data) if err != nil || back.Inputs2.Paths["src"] != paths["src"] || back.Inputs2.Tree != tree { t.Fatalf("decoded %+v, %v", back.Inputs2, err) } // What the indexer keeps must compute to the tree it kept: a mismatch is a value no recompute could give. bad := m bad.Inputs2 = &KeptInputs2{Tree: tree, Paths: map[string]string{"src": strings.Repeat("d", 40)}} if _, err := EncodeModule(bad); err == nil || !strings.Contains(err.Error(), "named tree") { t.Fatalf("kept paths that do not compute to the kept tree were accepted: %v", err) } // An older value has no paths, and its directory tree stays its tree. old := `{"v":1,"fp":"` + m.FP + `","manifest":"` + manifest + `","inputs2":{"tree":"` + strings.Repeat("e", 40) + `"},"repository":"novox/x","commit":"` + strings.Repeat("c", 40) + `"}` if o, err := DecodeModule([]byte(old)); err != nil || o.Inputs2.Paths != nil { t.Fatalf("an older value: %+v, %v", o, err) } f := Forge{Kind: ForgeMerged, Repository: "novox/mesh-sdk", Number: 1, Head: strings.Repeat("h", 40), Merge: strings.Repeat("m", 40), Root: strings.Repeat("r", 40), Trees: map[string]string{".": strings.Repeat("r", 40)}, Paths: map[string]map[string]string{".": paths}} data, err = EncodeForge(f) if err != nil { t.Fatal(err) } if fb, err := DecodeForge(data); err != nil || fb.Paths["."]["package.json"] != paths["package.json"] { t.Fatalf("decoded forge %+v, %v", fb.Paths, err) } f.Paths = map[string]map[string]string{"other": paths} if _, err := EncodeForge(f); err == nil { t.Fatal("named paths of a directory the message has no tree of were accepted") } f.Paths = map[string]map[string]string{".": {"src": ""}} if _, err := EncodeForge(f); err == nil { t.Fatal("a named path with no object was accepted") } p := Preview{Repository: "novox/mesh-sdk", Head: strings.Repeat("a", 40), Trunk: strings.Repeat("b", 40), Merge: strings.Repeat("c", 40), Modules: map[string]PreviewModule{".": {Tree: tree, Manifest: manifest, Paths: paths}}} data, err = EncodePreview(p) if err != nil { t.Fatal(err) } if pb, err := DecodePreview(data); err != nil || pb.Modules["."].Paths["src"] != paths["src"] { t.Fatalf("decoded preview %+v, %v", pb.Modules, err) } p.Modules["."] = PreviewModule{Tree: strings.Repeat("e", 40), Manifest: manifest, Paths: paths} if _, err := EncodePreview(p); err == nil || !strings.Contains(err.Error(), "named tree") { t.Fatalf("a preview whose tree is not its paths' named tree was accepted: %v", err) } }