From 34b74388a2ef38f8a981437630d9532bbb5ee6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20C=C3=A9sar=20Batista?= Date: Fri, 14 Apr 2023 10:52:27 -0300 Subject: [PATCH] add test --- e2etests-cli/main_test.go | 35 ++++++++++++++++++++++++++++++++++- lib/xgif/xgif.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/e2etests-cli/main_test.go b/e2etests-cli/main_test.go index 11e1b6f0e..63a58f178 100644 --- a/e2etests-cli/main_test.go +++ b/e2etests-cli/main_test.go @@ -10,6 +10,7 @@ import ( "oss.terrastruct.com/d2/d2cli" "oss.terrastruct.com/d2/lib/pptx" + "oss.terrastruct.com/d2/lib/xgif" "oss.terrastruct.com/util-go/assert" "oss.terrastruct.com/util-go/diff" "oss.terrastruct.com/util-go/xmain" @@ -141,7 +142,7 @@ a -> b: italic font run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { writeFile(t, dir, "x.d2", `x -> y`) err := runTestMain(t, ctx, dir, env, "--animate-interval=2", "x.d2", "x.png") - assert.ErrorString(t, err, `failed to wait xmain test: e2etests-cli/d2: bad usage: -animate-interval can only be used when exporting to SVG. + assert.ErrorString(t, err, `failed to wait xmain test: e2etests-cli/d2: bad usage: -animate-interval can only be used when exporting to SVG or GIF. You provided: .png`) }, }, @@ -277,6 +278,38 @@ steps: { assert.Success(t, err) }, }, + { + name: "how_to_solve_problems_gif", + skipCI: true, + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "in.d2", `how to solve a hard problem? { + link: steps.2 +} +steps: { + 1: { + w: write down the problem + } + 2: { + w -> t + t: think really hard about it + } + 3: { + t -> w2 + w2: write down the solution + w2: { + link: https://d2lang.com + } + } +} +`) + err := runTestMain(t, ctx, dir, env, "--animate-interval=10", "in.d2", "how_to_solve_problems.gif") + assert.Success(t, err) + + gifBytes := readFile(t, dir, "how_to_solve_problems.gif") + err = xgif.Validate(gifBytes, 4, 10) + assert.Success(t, err) + }, + }, { name: "stdin", run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { diff --git a/lib/xgif/xgif.go b/lib/xgif/xgif.go index f0c149712..20dccd0d0 100644 --- a/lib/xgif/xgif.go +++ b/lib/xgif/xgif.go @@ -89,3 +89,36 @@ func AnimatePNGs(pngs [][]byte, animIntervalMs int) ([]byte, error) { } return buf.Bytes(), nil } + +func Validate(gifBytes []byte, nFrames int, intervalMS int) error { + anim, err := gif.DecodeAll(bytes.NewBuffer(gifBytes)) + if err != nil { + return err + } + + if anim.LoopCount != INFINITE_LOOP { + return fmt.Errorf("expected infinite loop, got=%d", anim.LoopCount) + } + + if len(anim.Image) != nFrames { + return fmt.Errorf("expected %d frames, got=%d", nFrames, len(anim.Image)) + } + + interval := intervalMS / 10 + width, height := anim.Config.Width, anim.Config.Height + for i, frame := range anim.Image { + w := frame.Bounds().Dx() + if w != width { + return fmt.Errorf("expected all frames to have the same width=%d, got=%d at frame=%d", width, w, i) + } + h := frame.Bounds().Dy() + if h != height { + return fmt.Errorf("expected all frames to have the same height=%d, got=%d at frame=%d", height, h, i) + } + if anim.Delay[i] != interval { + return fmt.Errorf("expected interval between frames to be %d, got=%d at frame=%d", interval, anim.Delay[i], i) + } + } + + return nil +}