From 14f13d99e951c3f1737a4c8e8e57a5d0461fe0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Fo=C5=A1n=C3=A1r?= Date: Fri, 27 Jan 2023 22:57:50 +0100 Subject: [PATCH] added dark theme tests --- .../d2svg/dark_theme/dark_theme_test.go | 443 ++++++++++ .../testdata/all_shapes/dark_theme.exp.svg | 60 ++ .../testdata/animated/dark_theme.exp.svg | 73 ++ .../testdata/arrowheads/dark_theme.exp.svg | 75 ++ .../testdata/basic/dark_theme.exp.svg | 60 ++ .../child_to_child/dark_theme.exp.svg | 67 ++ .../testdata/class/dark_theme.exp.svg | 60 ++ .../connection_label/dark_theme.exp.svg | 67 ++ .../testdata/opacity/dark_theme.exp.svg | 817 +++++++++++++++++ .../testdata/overlay/dark_theme.exp.svg | 60 ++ .../testdata/sql_tables/dark_theme.exp.svg | 60 ++ .../testdata/twitter/dark_theme.exp.svg | 830 ++++++++++++++++++ 12 files changed, 2672 insertions(+) create mode 100644 d2renderers/d2svg/dark_theme/dark_theme_test.go create mode 100644 d2renderers/d2svg/dark_theme/testdata/all_shapes/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/arrowheads/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/basic/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/child_to_child/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/class/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/connection_label/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/overlay/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/sql_tables/dark_theme.exp.svg create mode 100644 d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg diff --git a/d2renderers/d2svg/dark_theme/dark_theme_test.go b/d2renderers/d2svg/dark_theme/dark_theme_test.go new file mode 100644 index 000000000..bb3280e4a --- /dev/null +++ b/d2renderers/d2svg/dark_theme/dark_theme_test.go @@ -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) +} diff --git a/d2renderers/d2svg/dark_theme/testdata/all_shapes/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/all_shapes/dark_theme.exp.svg new file mode 100644 index 000000000..c67a2ce77 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/all_shapes/dark_theme.exp.svg @@ -0,0 +1,60 @@ +rectanglesquarepageparallelogramdocumentcylinderqueuepackagestepcalloutstored_datapersondiamondovalcirclehexagoncloud + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg new file mode 100644 index 000000000..52af990bb --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/animated/dark_theme.exp.svg @@ -0,0 +1,73 @@ +wintersummertreessnowsun + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/arrowheads/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/arrowheads/dark_theme.exp.svg new file mode 100644 index 000000000..491b4053e --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/arrowheads/dark_theme.exp.svg @@ -0,0 +1,75 @@ +112233445566778899none arrow triangle diamond diamond filled cf-many cf-many-required cf-one cf-one-required + + + + + + + + + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/basic/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/basic/dark_theme.exp.svg new file mode 100644 index 000000000..e215fa941 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/basic/dark_theme.exp.svg @@ -0,0 +1,60 @@ +ab + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/child_to_child/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/child_to_child/dark_theme.exp.svg new file mode 100644 index 000000000..6690e7bdb --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/child_to_child/dark_theme.exp.svg @@ -0,0 +1,67 @@ +wintersummersnowsun + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/class/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/class/dark_theme.exp.svg new file mode 100644 index 000000000..4cfcde113 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/class/dark_theme.exp.svg @@ -0,0 +1,60 @@ +BatchManager-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)void + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/connection_label/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/connection_label/dark_theme.exp.svg new file mode 100644 index 000000000..ba15f7fb6 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/connection_label/dark_theme.exp.svg @@ -0,0 +1,67 @@ +ab hello + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg new file mode 100644 index 000000000..fd421a48e --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg @@ -0,0 +1,817 @@ +x

linux: because a PC is a terrible thing to waste

+
userslast_logindatetimea You don't have to know how the computer works,just how to work the computer. + + +
\ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/overlay/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/overlay/dark_theme.exp.svg new file mode 100644 index 000000000..d1e45d7d5 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/overlay/dark_theme.exp.svg @@ -0,0 +1,60 @@ +brightnormaldarkdarker + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/sql_tables/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/sql_tables/dark_theme.exp.svg new file mode 100644 index 000000000..33ba4a20c --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/sql_tables/dark_theme.exp.svg @@ -0,0 +1,60 @@ +usersidintnamestringemailstringpasswordstringlast_logindatetimeproductsidintpricedecimalskustringnamestringordersidintuser_idintproduct_idintshipmentsidintorder_idinttracking_numberstringPKstatusstring + + + \ No newline at end of file diff --git a/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg new file mode 100644 index 000000000..d82958447 --- /dev/null +++ b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg @@ -0,0 +1,830 @@ +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

Timeline mixer

+
    +
  • Inject ads, who-to-follow, onboarding
  • +
  • Conversation module
  • +
  • Cursoring,pagination
  • +
  • Tweat deduplication
  • +
  • Served data logging
  • +
+
GraphQLFederated Strato Column

Tweet/user content hydration, visibility filtering

+
TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone webHTTP AndroidThrift RPC Candidate FetchFeature HydrationCandidate sources + + + + + + + +
\ No newline at end of file