|
9 | 9 | "github.com/github/gh-stack/internal/git" |
10 | 10 | "github.com/github/gh-stack/internal/github" |
11 | 11 | "github.com/github/gh-stack/internal/stack" |
| 12 | + "github.com/spf13/cobra" |
12 | 13 | "github.com/stretchr/testify/assert" |
13 | 14 | "github.com/stretchr/testify/require" |
14 | 15 | ) |
@@ -62,11 +63,70 @@ func TestPush_PushesAllBranches(t *testing.T) { |
62 | 63 | assert.Equal(t, "origin", pushCalls[0].remote) |
63 | 64 | assert.Equal(t, []string{"b1", "b2"}, pushCalls[0].branches) |
64 | 65 | assert.True(t, pushCalls[0].force) |
65 | | - assert.False(t, pushCalls[0].atomic) |
| 66 | + assert.True(t, pushCalls[0].atomic) |
66 | 67 | assert.Contains(t, output, "Pushed 2 branches") |
67 | 68 | assert.Contains(t, output, "gh stack submit", "should hint about submit when branches have no PRs") |
68 | 69 | } |
69 | 70 |
|
| 71 | +func TestPush_AtomicOptions(t *testing.T) { |
| 72 | + for _, command := range []struct { |
| 73 | + name string |
| 74 | + newCmd func(*config.Config) *cobra.Command |
| 75 | + args []string |
| 76 | + force bool |
| 77 | + wantErr error |
| 78 | + }{ |
| 79 | + {"push", PushCmd, nil, true, ErrSilent}, |
| 80 | + {"submit", SubmitCmd, []string{"--auto"}, true, ErrSilent}, |
| 81 | + {"sync", SyncCmd, nil, false, nil}, |
| 82 | + {"link", LinkCmd, []string{"b1", "b2"}, false, ErrSilent}, |
| 83 | + } { |
| 84 | + for _, tc := range []struct { |
| 85 | + name string |
| 86 | + env string |
| 87 | + args []string |
| 88 | + atomic bool |
| 89 | + }{ |
| 90 | + {"default", "", nil, true}, |
| 91 | + {"flag", "", []string{"--no-atomic"}, false}, |
| 92 | + {"environment", "1", nil, false}, |
| 93 | + {"flag overrides environment", "1", []string{"--no-atomic=false"}, true}, |
| 94 | + } { |
| 95 | + t.Run(command.name+"/"+tc.name, func(t *testing.T) { |
| 96 | + t.Setenv("GH_STACK_NO_ATOMIC", tc.env) |
| 97 | + dir := t.TempDir() |
| 98 | + writeStackFile(t, dir, stack.Stack{ |
| 99 | + Trunk: stack.BranchRef{Branch: "main"}, |
| 100 | + Branches: []stack.BranchRef{{Branch: "b1"}, {Branch: "b2"}}, |
| 101 | + }) |
| 102 | + var pushes []pushCall |
| 103 | + mock := newSyncMock(dir, "b1") |
| 104 | + mock.RootDirFn = func() (string, error) { return dir, nil } |
| 105 | + mock.PushFn = func(remote string, branches []string, force, atomic bool) error { |
| 106 | + pushes = append(pushes, pushCall{remote, branches, force, atomic}) |
| 107 | + return assert.AnError |
| 108 | + } |
| 109 | + restore := git.SetOps(mock) |
| 110 | + defer restore() |
| 111 | + |
| 112 | + cfg, outR, errR := config.NewTestConfig() |
| 113 | + cfg.GitHubClientOverride = &github.MockClient{} |
| 114 | + cmd := command.newCmd(cfg) |
| 115 | + args := append([]string(nil), command.args...) |
| 116 | + cmd.SetArgs(append(args, tc.args...)) |
| 117 | + cmd.SetOut(io.Discard) |
| 118 | + cmd.SetErr(io.Discard) |
| 119 | + err := cmd.Execute() |
| 120 | + _, output := commandOutput(t, cfg, outR, errR) |
| 121 | + |
| 122 | + require.ErrorIs(t, err, command.wantErr, output) |
| 123 | + require.Len(t, pushes, 1, "failed pushes must not retry non-atomically") |
| 124 | + assert.Equal(t, pushCall{"origin", []string{"b1", "b2"}, command.force, tc.atomic}, pushes[0]) |
| 125 | + }) |
| 126 | + } |
| 127 | + } |
| 128 | +} |
| 129 | + |
70 | 130 | func TestPush_NoSubmitHintWhenPRsExist(t *testing.T) { |
71 | 131 | s := stack.Stack{ |
72 | 132 | Trunk: stack.BranchRef{Branch: "main"}, |
|
0 commit comments