package main import ( "context" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/forgekey" ) const baseSHA = "abcdef0123456789abcdef0123456789abcdef01" func commandLines(f *fakeMachine) string { var out []string for _, c := range f.calls { out = append(out, joined(c)) } return strings.Join(out, "\n") } // 1676/AC1: with a base the fetch merges the head onto it through the SDK's merge (the check merge's identity and flags, // hooks off), and answers the base, the merge commit, the changed paths and the tree, manifest and locks of each module // directory; the TypeScript modules are installed from the merged tree. func TestFetchWithABaseMergesAndAnswersThePreview(t *testing.T) { m, f := fetchMachine(t, typeScriptModule(`{"dependencies":{"@novox/mesh-sdk":"^0.1.6"}}`), nil) f.answer["git diff"] = forgekey.Ran{Stdout: "modules/m/package.json\n"} args := map[string]any{"repository": "novox/mesh-catalog", "commit": commitSHA, "base": baseSHA} out, err := m.fetch(context.Background(), args) if err != nil { t.Fatal(err) } r := out.(FetchResult) if r.Base != baseSHA || r.Merge != commitSHA || strings.Join(r.Changed, ",") != "modules/m/package.json" || len(r.Conflicts) != 0 { t.Errorf("result = %+v", r) } if mt, ok := r.Trees["modules/m"]; !ok || mt.Tree != commitSHA || mt.Manifest == "" { t.Errorf("trees = %+v", r.Trees) } if len(r.Modules) != 1 || r.Modules[0] != "modules/m" { t.Errorf("modules = %v", r.Modules) } for _, want := range []string{"fetch --no-tags origin " + baseSHA, "core.hooksPath=/dev/null", "merge --no-ff --no-edit --no-verify"} { if !strings.Contains(commandLines(f), want) { t.Errorf("git was not asked %q:\n%s", want, commandLines(f)) } } } // 1676/AC2: a conflict is an answer: the step passes with the files named, no merge commit, and nothing installed. func TestFetchWithAConflictAnswersTheFilesAndInstallsNothing(t *testing.T) { files := typeScriptModule(`{"dependencies":{"@novox/mesh-sdk":"^0.1.6","lodash":"^4"}}`) files["modules/m/package-lock.json"] = `{"lockfileVersion":3}` m, f := fetchMachine(t, files, nil) f.answer["git merge"] = forgekey.Ran{Status: 1, Stderr: "CONFLICT\n"} f.answer["git diff"] = forgekey.Ran{Stdout: "a.ts\nsub/b.ts\n"} out, err := m.fetch(context.Background(), map[string]any{"repository": "novox/mesh-catalog", "commit": commitSHA, "base": baseSHA}) if err != nil { t.Fatalf("a conflict failed the step: %v", err) } r := out.(FetchResult) if r.Merge != "" || strings.Join(r.Conflicts, ",") != "a.ts,sub/b.ts" || len(r.Changed) != 0 || len(npmCalls(f)) != 0 { t.Errorf("result = %+v, npm calls %d", r, len(npmCalls(f))) } if !strings.Contains(commandLines(f), "merge --abort") { t.Errorf("the merge was not undone:\n%s", commandLines(f)) } } // 1676/AC3: no base is today's fetch: no merge command, and none of the preview in the answer. func TestFetchWithoutABaseMakesNoMerge(t *testing.T) { m, f := fetchMachine(t, typeScriptModule(`{"dependencies":{"@novox/mesh-sdk":"^0.1.6"}}`), nil) out, err := m.fetch(context.Background(), fetchArgs) if err != nil { t.Fatal(err) } r := out.(FetchResult) if strings.Contains(commandLines(f), "merge") || strings.Contains(commandLines(f), "unshallow") || r.Base != "" || r.Merge != "" || r.Trees != nil { t.Errorf("a fetch without a base merged: %+v\n%s", r, commandLines(f)) } } func TestABaseThatIsNotACommitIsRefusedBeforeAnythingRuns(t *testing.T) { m, f := fetchMachine(t, nil, nil) if _, err := m.fetch(context.Background(), map[string]any{"repository": "novox/mesh-catalog", "commit": commitSHA, "base": "main"}); err == nil || len(f.calls) != 0 { t.Errorf("err = %v after %d commands", err, len(f.calls)) } }