Monorepo for Tangled tangled.org
858
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: test pull compose source parsing

Lewis: May this revision serve well! <lewis@tangled.org>

Lewis d2331dae 724d6c44

+322
+322
appview/pages/compose_parse_test.go
··· 1 + package pages 2 + 3 + import ( 4 + "bytes" 5 + "io" 6 + "log/slog" 7 + "strings" 8 + "testing" 9 + 10 + "tangled.org/core/appview/config" 11 + "tangled.org/core/appview/models" 12 + "tangled.org/core/appview/pages/repoinfo" 13 + "tangled.org/core/patchutil" 14 + "tangled.org/core/types" 15 + ) 16 + 17 + func TestPullComposeTemplatesParse(t *testing.T) { 18 + cfg := &config.Config{} 19 + p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil))) 20 + 21 + cases := []struct { 22 + name string 23 + stack []string 24 + }{ 25 + {"new.html via repo base", []string{"layouts/base", "layouts/repobase", "repo/pulls/new"}}, 26 + {"pullComposeHost", []string{"repo/pulls/fragments/pullComposeHost"}}, 27 + {"pullStepSource", []string{"repo/pulls/fragments/pullStepSource"}}, 28 + {"pullStepReview", []string{"repo/pulls/fragments/pullStepReview"}}, 29 + {"pullStepDetails", []string{"repo/pulls/fragments/pullStepDetails"}}, 30 + {"pullCompareForks", []string{"repo/pulls/fragments/pullCompareForks"}}, 31 + {"pullCompareBranches", []string{"repo/pulls/fragments/pullCompareBranches"}}, 32 + {"pullCompareForksBranches", []string{"repo/pulls/fragments/pullCompareForksBranches"}}, 33 + } 34 + 35 + for _, c := range cases { 36 + t.Run(c.name, func(t *testing.T) { 37 + if _, err := p.rawParse(c.stack...); err != nil { 38 + t.Fatalf("parse %v: %v", c.stack, err) 39 + } 40 + }) 41 + } 42 + } 43 + 44 + func TestPullComposeHostRender(t *testing.T) { 45 + cfg := &config.Config{} 46 + p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil))) 47 + 48 + base := RepoNewPullParams{ 49 + RepoInfo: repoinfo.RepoInfo{ 50 + OwnerDid: "did:plc:test", 51 + Name: "test-repo", 52 + }, 53 + } 54 + 55 + for _, source := range []Source{"", SourceBranch, SourceFork, SourcePatch} { 56 + for _, stacked := range []bool{false, true} { 57 + if source == SourcePatch && stacked { 58 + continue 59 + } 60 + params := base 61 + params.Source = source 62 + params.IsStacked = stacked 63 + name := string(source) 64 + if name == "" { 65 + name = "default" 66 + } 67 + if stacked { 68 + name += "-stacked" 69 + } 70 + t.Run(name, func(t *testing.T) { 71 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 72 + t.Fatalf("render source=%q stacked=%v: %v", source, stacked, err) 73 + } 74 + }) 75 + } 76 + } 77 + } 78 + 79 + func TestPullComposeHostRenderWithData(t *testing.T) { 80 + cfg := &config.Config{} 81 + p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil))) 82 + 83 + sampleBranches := []types.Branch{ 84 + {Reference: types.Reference{Name: "feature"}}, 85 + {Reference: types.Reference{Name: "main"}, IsDefault: true}, 86 + } 87 + 88 + formatPatch := `From 1111111111111111111111111111111111111111 Mon Sep 11 00:00:00 2001 89 + From: Test <test@best.fest> 90 + Date: Tue, 1 Jan 2020 00:00:00 +0000 91 + Subject: [PATCH] example commit 92 + 93 + --- 94 + a.txt | 1 + 95 + 1 file changed, 1 insertion(+) 96 + 97 + diff --git a/a.txt b/a.txt 98 + index 0000000..1111111 100644 99 + --- a/a.txt 100 + +++ b/a.txt 101 + @@ -0,0 +1 @@ 102 + +hello 103 + ` 104 + patches, err := patchutil.ExtractPatches(formatPatch) 105 + if err != nil { 106 + t.Fatalf("extract patches: %v", err) 107 + } 108 + comparison := &types.RepoFormatPatchResponse{ 109 + FormatPatchRaw: formatPatch, 110 + FormatPatch: patches, 111 + } 112 + diff := patchutil.AsNiceDiff(formatPatch, "main") 113 + 114 + params := RepoNewPullParams{ 115 + RepoInfo: repoinfo.RepoInfo{ 116 + OwnerDid: "did:plc:test", 117 + Name: "test-repo", 118 + }, 119 + Branches: sampleBranches, 120 + SourceBranches: []types.Branch{sampleBranches[0]}, 121 + ForkBranches: []types.Branch{sampleBranches[0]}, 122 + Source: SourceBranch, 123 + SourceBranch: "feature", 124 + TargetBranch: "main", 125 + Comparison: comparison, 126 + Diff: &diff, 127 + } 128 + 129 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 130 + t.Fatalf("render with data: %v", err) 131 + } 132 + 133 + params.IsStacked = true 134 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 135 + t.Fatalf("render stacked: %v", err) 136 + } 137 + 138 + params.PrefillError = "branch not found" 139 + params.Comparison = nil 140 + params.Diff = nil 141 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 142 + t.Fatalf("render with prefill error: %v", err) 143 + } 144 + 145 + bugDef := &models.LabelDefinition{ 146 + Did: "did:plc:test", 147 + Rkey: "bug", 148 + Name: "bug", 149 + ValueType: models.ValueType{Type: models.ConcreteTypeNull}, 150 + Scope: []string{"sh.tangled.repo.pull"}, 151 + } 152 + priorityDef := &models.LabelDefinition{ 153 + Did: "did:plc:test", 154 + Rkey: "priority", 155 + Name: "priority", 156 + ValueType: models.ValueType{Type: models.ConcreteTypeString, Enum: []string{"low", "med", "high"}}, 157 + Scope: []string{"sh.tangled.repo.pull"}, 158 + } 159 + assigneeDef := &models.LabelDefinition{ 160 + Did: "did:plc:test", 161 + Rkey: "assignee", 162 + Name: "assignee", 163 + ValueType: models.ValueType{Type: models.ConcreteTypeString, Format: models.ValueTypeFormatDid}, 164 + Scope: []string{"sh.tangled.repo.pull"}, 165 + Multiple: true, 166 + } 167 + labelDefs := map[string]*models.LabelDefinition{ 168 + bugDef.AtUri().String(): bugDef, 169 + priorityDef.AtUri().String(): priorityDef, 170 + assigneeDef.AtUri().String(): assigneeDef, 171 + } 172 + 173 + pushRepoInfo := repoinfo.RepoInfo{ 174 + OwnerDid: "did:plc:test", 175 + Name: "test-repo", 176 + Roles: repoinfo.RolesInRepo{Roles: []string{"repo:push"}}, 177 + } 178 + params = RepoNewPullParams{ 179 + RepoInfo: pushRepoInfo, 180 + Branches: sampleBranches, 181 + SourceBranches: []types.Branch{sampleBranches[0]}, 182 + Source: SourceBranch, 183 + SourceBranch: "feature", 184 + TargetBranch: "main", 185 + Comparison: comparison, 186 + Diff: &diff, 187 + LabelDefs: labelDefs, 188 + LabelState: models.NewLabelState(), 189 + } 190 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 191 + t.Fatalf("render with labels: %v", err) 192 + } 193 + 194 + params.IsStacked = true 195 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 196 + t.Fatalf("render stacked with labels: %v", err) 197 + } 198 + 199 + params.StackedDiffs = []StackedDiff{{ 200 + Diff: &diff, 201 + Opts: types.DiffOpts{Split: true, RefreshUrl: "/r", Target: "#stack-diff-x", Field: "stackSplit[x]"}, 202 + }} 203 + if err := p.PullComposeHostFragment(io.Discard, params); err != nil { 204 + t.Fatalf("render stacked with per-commit diffs: %v", err) 205 + } 206 + } 207 + 208 + func TestPullComposeLabelStateRoundTrip(t *testing.T) { 209 + cfg := &config.Config{} 210 + p := NewPages(cfg, nil, nil, nil, slog.New(slog.NewTextHandler(io.Discard, nil))) 211 + 212 + sampleBranches := []types.Branch{ 213 + {Reference: types.Reference{Name: "feature"}}, 214 + {Reference: types.Reference{Name: "main"}, IsDefault: true}, 215 + } 216 + 217 + bugDef := &models.LabelDefinition{ 218 + Did: "did:plc:test", Rkey: "bug", Name: "bug", 219 + ValueType: models.ValueType{Type: models.ConcreteTypeNull}, 220 + Scope: []string{"sh.tangled.repo.pull"}, 221 + } 222 + priorityDef := &models.LabelDefinition{ 223 + Did: "did:plc:test", Rkey: "priority", Name: "priority", 224 + ValueType: models.ValueType{Type: models.ConcreteTypeString, Enum: []string{"low", "med", "high"}}, 225 + Scope: []string{"sh.tangled.repo.pull"}, 226 + } 227 + bugKey := bugDef.AtUri().String() 228 + priorityKey := priorityDef.AtUri().String() 229 + labelDefs := map[string]*models.LabelDefinition{ 230 + bugKey: bugDef, 231 + priorityKey: priorityDef, 232 + } 233 + 234 + state := models.NewLabelState() 235 + actx := &models.LabelApplicationCtx{Defs: labelDefs} 236 + for _, op := range []models.LabelOp{ 237 + {OperandKey: bugKey, OperandValue: "null", Operation: models.LabelOperationAdd}, 238 + {OperandKey: priorityKey, OperandValue: "high", Operation: models.LabelOperationAdd}, 239 + } { 240 + if err := actx.ApplyLabelOp(state, op); err != nil { 241 + t.Fatalf("seed state: %v", err) 242 + } 243 + } 244 + 245 + formatPatch := `From 1111111111111111111111111111111111111111 Mon Sep 11 00:00:00 2001 246 + From: Test <test@best.fest> 247 + Date: Tue, 1 Jan 2020 00:00:00 +0000 248 + Subject: [PATCH] example commit 249 + 250 + --- 251 + a.txt | 1 + 252 + 1 file changed, 1 insertion(+) 253 + 254 + diff --git a/a.txt b/a.txt 255 + index 0000000..1111111 100644 256 + --- a/a.txt 257 + +++ b/a.txt 258 + @@ -0,0 +1 @@ 259 + +hello 260 + ` 261 + patches, err := patchutil.ExtractPatches(formatPatch) 262 + if err != nil { 263 + t.Fatalf("extract patches: %v", err) 264 + } 265 + comparison := &types.RepoFormatPatchResponse{ 266 + FormatPatchRaw: formatPatch, 267 + FormatPatch: patches, 268 + } 269 + 270 + params := RepoNewPullParams{ 271 + RepoInfo: repoinfo.RepoInfo{ 272 + OwnerDid: "did:plc:test", 273 + Name: "test-repo", 274 + Roles: repoinfo.RolesInRepo{Roles: []string{"repo:push"}}, 275 + }, 276 + Branches: sampleBranches, 277 + SourceBranches: []types.Branch{sampleBranches[0]}, 278 + Source: SourceBranch, 279 + SourceBranch: "feature", 280 + TargetBranch: "main", 281 + Comparison: comparison, 282 + LabelDefs: labelDefs, 283 + LabelState: state, 284 + } 285 + 286 + var buf bytes.Buffer 287 + if err := p.PullComposeHostFragment(&buf, params); err != nil { 288 + t.Fatalf("render: %v", err) 289 + } 290 + out := buf.String() 291 + for _, want := range []string{ 292 + `value="null" checked`, 293 + `value="high" checked`, 294 + } { 295 + if !strings.Contains(out, want) { 296 + t.Errorf("missing pre-selection %q", want) 297 + } 298 + } 299 + } 300 + 301 + func TestParseSource(t *testing.T) { 302 + cases := []struct { 303 + in string 304 + want Source 305 + wantOk bool 306 + }{ 307 + {"branch", SourceBranch, true}, 308 + {"BRANCH", SourceBranch, true}, 309 + {"fork", SourceFork, true}, 310 + {"patch", SourcePatch, true}, 311 + {"", "", false}, 312 + {"method", "", false}, 313 + {"strategy", "", false}, 314 + {"unknown", "", false}, 315 + } 316 + for _, c := range cases { 317 + got, ok := ParseSource(c.in) 318 + if got != c.want || ok != c.wantOk { 319 + t.Errorf("ParseSource(%q) = %q, %v; want %q, %v", c.in, got, ok, c.want, c.wantOk) 320 + } 321 + } 322 + }