A Before observer mutating inv.Args() must not affect what the original RunE sees: pins the slice-level read-only contract.
(t *testing.T)
| 347 | // A Before observer mutating inv.Args() must not affect what the |
| 348 | // original RunE sees: pins the slice-level read-only contract. |
| 349 | func TestInstall_argsNotMutableByObserver(t *testing.T) { |
| 350 | root := &cobra.Command{Use: "lark-cli"} |
| 351 | |
| 352 | var seenByRunE []string |
| 353 | leaf := &cobra.Command{ |
| 354 | Use: "+echo", |
| 355 | RunE: func(_ *cobra.Command, args []string) error { |
| 356 | seenByRunE = append([]string(nil), args...) |
| 357 | return nil |
| 358 | }, |
| 359 | } |
| 360 | root.AddCommand(leaf) |
| 361 | |
| 362 | reg := hook.NewRegistry() |
| 363 | reg.AddObserver(hook.ObserverEntry{ |
| 364 | Name: "tamper", When: platform.Before, Selector: platform.All(), |
| 365 | Fn: func(_ context.Context, inv platform.Invocation) { |
| 366 | got := inv.Args() |
| 367 | if len(got) > 0 { |
| 368 | got[0] = "HIJACKED" |
| 369 | } |
| 370 | }, |
| 371 | }) |
| 372 | hook.Install(root, reg, fakeViewSource{view: fakeView{path: "+echo"}}) |
| 373 | |
| 374 | originalArgs := []string{"hello", "world"} |
| 375 | if err := leaf.RunE(leaf, originalArgs); err != nil { |
| 376 | t.Fatalf("RunE returned %v", err) |
| 377 | } |
| 378 | if !equalStrings(seenByRunE, originalArgs) { |
| 379 | t.Fatalf("RunE saw mutated args: got %v, want %v", seenByRunE, originalArgs) |
| 380 | } |
| 381 | if originalArgs[0] != "hello" { |
| 382 | t.Fatalf("caller's original args were mutated: %v", originalArgs) |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | // Root command (no parent) must never be wrapped -- it dispatches help |
| 387 | // and other framework concerns. The root has no RunE so we instead |
nothing calls this directly
no test coverage detected