added dark theme tests

This commit is contained in:
Vojtěch Fošnár 2023-01-27 22:57:50 +01:00
parent d24a5c1ec3
commit 14f13d99e9
No known key found for this signature in database
GPG key ID: 657727E71C40859A
12 changed files with 2672 additions and 0 deletions

View file

@ -0,0 +1,443 @@
package dark_theme_test
import (
"context"
"encoding/xml"
"io/ioutil"
"math"
"os"
"path/filepath"
"strings"
"testing"
"cdr.dev/slog"
tassert "github.com/stretchr/testify/assert"
"oss.terrastruct.com/util-go/assert"
"oss.terrastruct.com/util-go/diff"
"oss.terrastruct.com/util-go/go2"
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2renderers/d2fonts"
"oss.terrastruct.com/d2/d2renderers/d2svg"
"oss.terrastruct.com/d2/lib/log"
"oss.terrastruct.com/d2/lib/textmeasure"
)
func TestDarkTheme(t *testing.T) {
t.Parallel()
tcs := []testCase{
{
name: "basic",
script: `a -> b
`,
},
{
name: "child to child",
script: `winter.snow -> summer.sun
`,
},
{
name: "animated",
script: `winter.snow -> summer.sun -> trees -> winter.snow: { style.animated: true }
`,
},
{
name: "connection label",
script: `a -> b: hello
`,
},
{
name: "twitter",
script: `timeline mixer: "" {
explanation: |md
## **Timeline mixer**
- Inject ads, who-to-follow, onboarding
- Conversation module
- Cursoring,pagination
- Tweat deduplication
- Served data logging
|
}
People discovery: "People discovery \nservice"
admixer: Ad mixer {
fill: "#cba6f7"
font-color: "#000000"
}
onboarding service: "Onboarding \nservice"
timeline mixer -> People discovery
timeline mixer -> onboarding service
timeline mixer -> admixer
container0: "" {
graphql
comment
tlsapi
}
container0.graphql: GraphQL\nFederated Strato Column {
shape: image
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/1200px-GraphQL_Logo.svg.png
}
container0.comment: |md
## Tweet/user content hydration, visibility filtering
|
container0.tlsapi: TLS-API (being deprecated)
container0.graphql -> timeline mixer
timeline mixer <- container0.tlsapi
twitter fe: "Twitter Frontend " {
icon: https://icons.terrastruct.com/social/013-twitter-1.svg
shape: image
}
twitter fe -> container0.graphql: iPhone web
twitter fe -> container0.tlsapi: HTTP Android
web: Web {
icon: https://icons.terrastruct.com/azure/Web%20Service%20Color/App%20Service%20Domains.svg
shape: image
}
Iphone: {
icon: 'https://ss7.vzw.com/is/image/VerizonWireless/apple-iphone-12-64gb-purple-53017-mjn13ll-a?$device-lg$'
shape: image
}
Android: {
icon: https://cdn4.iconfinder.com/data/icons/smart-phones-technologies/512/android-phone.png
shape: image
}
web -> twitter fe
timeline scorer: "Timeline\nScorer" {
fill: "#fab387"
font-color: "#000000"
}
home ranker: Home Ranker
timeline service: Timeline Service
timeline mixer -> timeline scorer: Thrift RPC
timeline mixer -> home ranker: {
style.stroke-dash: 4
style.stroke: "#000E3D"
}
timeline mixer -> timeline service
home mixer: Home mixer {
# fill: "#c1a2f3"
}
container0.graphql -> home mixer: {
style.stroke-dash: 4
style.stroke: "#000E3D"
}
home mixer -> timeline scorer
home mixer -> home ranker: {
style.stroke-dash: 4
style.stroke: "#000E3D"
}
home mixer -> timeline service
manhattan 2: Manhattan
gizmoduck: Gizmoduck
socialgraph: Social graph
tweetypie: Tweety Pie
home mixer -> manhattan 2
home mixer -> gizmoduck
home mixer -> socialgraph
home mixer -> tweetypie
Iphone -> twitter fe
Android -> twitter fe
prediction service2: Prediction Service {
shape: image
icon: https://cdn-icons-png.flaticon.com/512/6461/6461819.png
}
home scorer: Home Scorer {
fill: "#eba0ac"
font-color: "#000000"
}
manhattan: Manhattan
memcache: Memcache {
icon: https://d1q6f0aelx0por.cloudfront.net/product-logos/de041504-0ddb-43f6-b89e-fe04403cca8d-memcached.png
}
fetch: Fetch {
multiple: true
shape: step
}
feature: Feature {
multiple: true
shape: step
}
scoring: Scoring {
multiple: true
shape: step
}
fetch -> feature
feature -> scoring
prediction service: Prediction Service {
shape: image
icon: https://cdn-icons-png.flaticon.com/512/6461/6461819.png
}
scoring -> prediction service
fetch -> container2.crmixer
home scorer -> manhattan: ""
home scorer -> memcache: ""
home scorer -> prediction service2
home ranker -> home scorer
home ranker -> container2.crmixer: Candidate Fetch
container2: "" {
style.stroke: "#b4befe"
style.fill: "#000000"
crmixer: CrMixer {
style.fill: "#11111b"
style.font-color: "#cdd6f4"
}
earlybird: EarlyBird
utag: Utag
space: Space
communities: Communities
}
etc: ...etc
home scorer -> etc: Feature Hydration
feature -> manhattan
feature -> memcache
feature -> etc: Candidate sources
`,
},
{
name: "all_shapes",
script: `
rectangle: {shape: "rectangle"}
square: {shape: "square"}
page: {shape: "page"}
parallelogram: {shape: "parallelogram"}
document: {shape: "document"}
cylinder: {shape: "cylinder"}
queue: {shape: "queue"}
package: {shape: "package"}
step: {shape: "step"}
callout: {shape: "callout"}
stored_data: {shape: "stored_data"}
person: {shape: "person"}
diamond: {shape: "diamond"}
oval: {shape: "oval"}
circle: {shape: "circle"}
hexagon: {shape: "hexagon"}
cloud: {shape: "cloud"}
rectangle -> square -> page
parallelogram -> document -> cylinder
queue -> package -> step
callout -> stored_data -> person
diamond -> oval -> circle
hexagon -> cloud
`,
},
{
name: "sql_tables",
script: `users: {
shape: sql_table
id: int
name: string
email: string
password: string
last_login: datetime
}
products: {
shape: sql_table
id: int
price: decimal
sku: string
name: string
}
orders: {
shape: sql_table
id: int
user_id: int
product_id: int
}
shipments: {
shape: sql_table
id: int
order_id: int
tracking_number: string {constraint: primary_key}
status: string
}
users.id <-> orders.user_id
products.id <-> orders.product_id
shipments.order_id <-> orders.id`,
},
{
name: "class",
script: `manager: BatchManager {
shape: class
-num: int
-timeout: int
-pid
+getStatus(): Enum
+getJobs(): "Job[]"
+setTimeout(seconds int)
}
`,
},
{
name: "arrowheads",
script: `
a: ""
b: ""
a.1 -- b.1: none
a.2 <-> b.2: arrow {
source-arrowhead.shape: arrow
target-arrowhead.shape: arrow
}
a.3 <-> b.3: triangle {
source-arrowhead.shape: triangle
target-arrowhead.shape: triangle
}
a.4 <-> b.4: diamond {
source-arrowhead.shape: diamond
target-arrowhead.shape: diamond
}
a.5 <-> b.5: diamond filled {
source-arrowhead: {
shape: diamond
style.filled: true
}
target-arrowhead: {
shape: diamond
style.filled: true
}
}
a.6 <-> b.6: cf-many {
source-arrowhead.shape: cf-many
target-arrowhead.shape: cf-many
}
a.7 <-> b.7: cf-many-required {
source-arrowhead.shape: cf-many-required
target-arrowhead.shape: cf-many-required
}
a.8 <-> b.8: cf-one {
source-arrowhead.shape: cf-one
target-arrowhead.shape: cf-one
}
a.9 <-> b.9: cf-one-required {
source-arrowhead.shape: cf-one-required
target-arrowhead.shape: cf-one-required
}
`,
},
{
name: "opacity",
script: `x.style.opacity: 0.4
y: |md
linux: because a PC is a terrible thing to waste
| {
style.opacity: 0.4
}
x -> a: {
label: You don't have to know how the computer works,\njust how to work the computer.
style.opacity: 0.4
}
users: {
shape: sql_table
last_login: datetime
style.opacity: 0.4
}
`,
},
{
name: "overlay",
script: `bright: {
style.stroke: "#000"
style.font-color: "#000"
style.fill: "#fff"
}
normal: {
style.stroke: "#000"
style.font-color: "#000"
style.fill: "#ccc"
}
dark: {
style.stroke: "#000"
style.font-color: "#fff"
style.fill: "#555"
}
darker: {
style.stroke: "#000"
style.font-color: "#fff"
style.fill: "#000"
}
`,
},
}
runa(t, tcs)
}
type testCase struct {
name string
script string
skip bool
}
func runa(t *testing.T, tcs []testCase) {
for _, tc := range tcs {
tc := tc
t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
t.Parallel()
run(t, tc)
})
}
}
func run(t *testing.T, tc testCase) {
ctx := context.Background()
ctx = log.WithTB(ctx, t, nil)
ctx = log.Leveled(ctx, slog.LevelDebug)
ruler, err := textmeasure.NewRuler()
if !tassert.Nil(t, err) {
return
}
diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{
Ruler: ruler,
Layout: d2dagrelayout.DefaultLayout,
FontFamily: go2.Pointer(d2fonts.HandDrawn),
})
if !tassert.Nil(t, err) {
return
}
dataPath := filepath.Join("testdata", strings.TrimPrefix(t.Name(), "TestDarkTheme/"))
pathGotSVG := filepath.Join(dataPath, "dark_theme.got.svg")
svgBytes, err := d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: d2svg.DEFAULT_PADDING,
ThemeID: 200,
DarkThemeID: math.MaxInt64,
})
assert.Success(t, err)
err = os.MkdirAll(dataPath, 0755)
assert.Success(t, err)
err = ioutil.WriteFile(pathGotSVG, svgBytes, 0600)
assert.Success(t, err)
defer os.Remove(pathGotSVG)
var xmlParsed interface{}
err = xml.Unmarshal(svgBytes, &xmlParsed)
assert.Success(t, err)
err = diff.Testdata(filepath.Join(dataPath, "dark_theme"), ".svg", svgBytes)
assert.Success(t, err)
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 198 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 240 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 254 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 188 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 238 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 189 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 238 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 299 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 188 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 65 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 320 KiB