• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mermaid-js / mermaid / 4128116375

pending completion
4128116375

push

github

GitHub
chore(deps): update timonvs/pr-labeler-action action to v4

1567 of 1949 branches covered (80.4%)

Branch coverage included in aggregate %.

15429 of 30282 relevant lines covered (50.95%)

450.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.21
/packages/mermaid/src/tests/MockedD3.ts
1
import type {} from '@vitest/spy';
1✔
2

1✔
3
/**
1✔
4
 * This is a mocked/stubbed version of the d3 Selection type. Each of the main functions are all
1✔
5
 * mocked (via vi.fn()) so you can track if they have been called, etc.
1✔
6
 *
1✔
7
 * Note that node() returns a HTML Element with tag 'svg'. It is an empty element (no innerHTML, no children, etc).
1✔
8
 * This potentially allows testing of mermaidAPI render().
1✔
9
 */
1✔
10

1✔
11
export class MockedD3 {
1✔
12
  public attribs = new Map<string, string | null>();
1✔
13
  public id: string | undefined = '';
1✔
14
  _children: MockedD3[] = [];
1✔
15

1✔
16
  _containingHTMLdoc = new Document();
1✔
17

1✔
18
  constructor(givenId = 'mock-id') {
1✔
19
    this.id = givenId;
330✔
20
  }
330✔
21

1✔
22
  /** Helpful utility during development/debugging. This is not a real d3 function */
1✔
23
  public listChildren(): string {
1✔
24
    return this._children
×
25
      .map((child) => {
×
26
        return child.id;
×
27
      })
×
28
      .join(', ');
×
29
  }
×
30

1✔
31
  select = vi.fn().mockImplementation(({ select_str = '' }): MockedD3 => {
1✔
32
    // Get the id from an argument string. if it is of the form [id='some-id'], strip off the
130✔
33
    // surrounding id[..]
130✔
34
    const stripSurroundRegexp = /\[id='(.*)']/;
130✔
35
    const matchedSurrounds = select_str.match(stripSurroundRegexp);
130✔
36
    const cleanId = matchedSurrounds ? matchedSurrounds[1] : select_str;
130!
37
    return new MockedD3(cleanId);
130✔
38
  });
1✔
39

1✔
40
  // This has the same implementation as select(). (It calls it.)
1✔
41
  selectAll = vi.fn().mockImplementation(({ select_str = '' }): MockedD3 => {
1✔
42
    return this.select(select_str);
26✔
43
  });
1✔
44

1✔
45
  append = vi
1✔
46
    .fn()
1✔
47
    .mockImplementation(function (this: MockedD3, type: string, id = '' + '-appended'): MockedD3 {
1✔
48
      const newMock = new MockedD3(id);
78✔
49
      newMock.attribs.set('type', type);
78✔
50
      this._children.push(newMock);
78✔
51
      return newMock;
78✔
52
    });
1✔
53

1✔
54
  // NOTE: The d3 implementation allows for a selector ('beforeSelector' arg below).
1✔
55
  //   With this mocked implementation, we assume it will always refer to an node id
1✔
56
  //   and will always be of the form "#[id of the node to insert before]".
1✔
57
  //   To keep this simple, any leading '#' is removed and the resulting string is the node id searched.
1✔
58
  insert = (type: string, beforeSelector?: string, id = this.id + '-inserted'): MockedD3 => {
1✔
59
    const newMock = new MockedD3(id);
4✔
60
    newMock.attribs.set('type', type);
4✔
61
    if (beforeSelector === undefined) {
4!
62
      this._children.push(newMock);
×
63
    } else {
4✔
64
      const idOnly = beforeSelector[0] == '#' ? beforeSelector.substring(1) : beforeSelector;
4!
65
      const foundIndex = this._children.findIndex((child) => child.id === idOnly);
4✔
66
      if (foundIndex < 0) {
4✔
67
        this._children.push(newMock);
4✔
68
      } else {
4!
69
        this._children.splice(foundIndex, 0, newMock);
×
70
      }
×
71
    }
4✔
72
    return newMock;
4✔
73
  };
4✔
74

1✔
75
  attr(attrName: string): null | undefined | string | number;
1✔
76
  // attr(attrName: string, attrValue: string): MockedD3;
1✔
77
  attr(attrName: string, attrValue?: string): null | undefined | string | number | MockedD3 {
1✔
78
    if (arguments.length === 1) {
176✔
79
      return this.attribs.get(attrName);
26✔
80
    } else {
176✔
81
      if (attrName === 'id') {
150✔
82
        this.id = attrValue; // also set the id explicitly
60✔
83
      }
60✔
84
      if (attrValue !== undefined) {
150✔
85
        this.attribs.set(attrName, attrValue);
150✔
86
      }
150✔
87
      return this;
150✔
88
    }
150✔
89
  }
176✔
90

1✔
91
  public lower(attrValue = '') {
1✔
92
    this.attribs.set('lower', attrValue);
×
93
    return this;
×
94
  }
×
95
  public style(attrValue = '') {
1✔
96
    this.attribs.set('style', attrValue);
×
97
    return this;
×
98
  }
×
99
  public text(attrValue = '') {
1✔
100
    this.attribs.set('text', attrValue);
20✔
101
    return this;
20✔
102
  }
20✔
103

1✔
104
  // NOTE: Returns a HTML Element with tag 'svg' that has _another_ 'svg' element child.
1✔
105
  // This allows different tests to succeed -- some need a top level 'svg' and some need a 'svg' element to be the firstChild
1✔
106
  // Real implementation returns an HTML Element
1✔
107
  public node = vi.fn().mockImplementation(() => {
1✔
108
    const topElem = this._containingHTMLdoc.createElement('svg');
78✔
109
    const elem_svgChild = this._containingHTMLdoc.createElement('svg'); // another svg element
78✔
110
    topElem.appendChild(elem_svgChild);
78✔
111
    return topElem;
78✔
112
  });
1✔
113

1✔
114
  // TODO Is this correct? shouldn't it return a list of HTML Elements?
1✔
115
  nodes = vi.fn().mockImplementation(function (this: MockedD3): MockedD3[] {
1✔
116
    return this._children;
×
117
  });
1✔
118

1✔
119
  // This will try to use attrs that have been set.
1✔
120
  getBBox = () => {
1✔
121
    const x = this.attribs.has('x') ? this.attribs.get('x') : 20;
×
122
    const y = this.attribs.has('y') ? this.attribs.get('y') : 30;
×
123
    const width = this.attribs.has('width') ? this.attribs.get('width') : 140;
×
124
    const height = this.attribs.has('height') ? this.attribs.get('height') : 250;
×
125
    return {
×
126
      x: x,
×
127
      y: y,
×
128
      width: width,
×
129
      height: height,
×
130
    };
×
131
  };
×
132

1✔
133
  // --------------------------------------------------------------------------------
1✔
134
  // The following functions are here for completeness.  They simply return a vi.fn()
1✔
135

1✔
136
  insertBefore = vi.fn();
1✔
137
  curveBasis = vi.fn();
1✔
138
  curveBasisClosed = vi.fn();
1✔
139
  curveBasisOpen = vi.fn();
1✔
140
  curveLinear = vi.fn();
1✔
141
  curveLinearClosed = vi.fn();
1✔
142
  curveMonotoneX = vi.fn();
1✔
143
  curveMonotoneY = vi.fn();
1✔
144
  curveNatural = vi.fn();
1✔
145
  curveStep = vi.fn();
1✔
146
  curveStepAfter = vi.fn();
1✔
147
  curveStepBefore = vi.fn();
1✔
148
}
118✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc