Monorepo for Tangled
0

Configure Feed

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

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