From ed29fe1aa9257c55e1afb37cc35f63de347d979b Mon Sep 17 00:00:00 2001 From: Paik Paustian Date: Sun, 3 Jul 2022 11:41:18 +0200 Subject: [PATCH 01/13] Fix #3011: Support left- and right-alignment for multi-line messages and notes Previously, messages and notes that had multiple lines (via `
`-tags) were only displayed correctly when using the default `center` value for the `messageAlign` and `noteAlign` configuration options. Using `left` or `right` for the alignment options caused the text to collapse and become illegible, as outlined in issue #3011. This comes as a side-effect from how the internal `valign` text-rendering option was configured for messages and notes: ```js // Example from `sequenceRenderer.js: drawMessage()` textObj.anchor = conf.messageAlign; textObj.valign = conf.messageAlign; ``` Both the `anchor` option (which controls left-right alignment) and the `valign` option (which controls vertical top-down placement) were set to the same value, the user-provided `messageAlign` config option. While `left` and `right` are valid values for the `anchor` option, they were effectively no-ops for the `valign` option, which only supports `top`, `start`, `middle`, `center`, `bottom`, and `end`. To fix the issue, the `valign` property is now always set to `center` for notes and messages. Similarly, the `dominantBaseline` option of texts is now always set to `middle`, rather than setting it to either `text-{before,after}-edge`, which caused left-aligned multi-line text to always be "top-left" aligned inside a note (or "bottom-right" when attempting to right-align). Now, texts in messages and notes are always vertically centered and alignment options correctly apply for both single and multi-line content. --- cypress/e2e/rendering/sequencediagram.spec.js | 42 +++++++++++++++++++ src/diagrams/sequence/sequenceRenderer.js | 4 +- src/diagrams/sequence/svgDraw.js | 4 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/cypress/e2e/rendering/sequencediagram.spec.js b/cypress/e2e/rendering/sequencediagram.spec.js index c110f05ada9..0559cce20b7 100644 --- a/cypress/e2e/rendering/sequencediagram.spec.js +++ b/cypress/e2e/rendering/sequencediagram.spec.js @@ -126,6 +126,17 @@ context('Sequence diagram', () => { { sequence: { noteAlign: 'left' } } ); }); + it('should render multi-line notes aligned to the left when configured', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice->>Bob: I'm short + note left of Alice: I am left aligned
but also
multiline + Bob->>Alice: Short as well + `, + { sequence: { noteAlign: 'left' } } + ); + }); it('should render notes aligned to the right when configured', () => { imgSnapshotTest( ` @@ -137,6 +148,37 @@ context('Sequence diagram', () => { { sequence: { noteAlign: 'right' } } ); }); + it('should render multi-line notes aligned to the right when configured', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice->>Bob: I'm short + note left of Alice: I am right aligned
but also
multiline + Bob->>Alice: Short as well + `, + { sequence: { noteAlign: 'right' } } + ); + }); + it('should render multi-line messages aligned to the left when configured', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice->>Bob: I'm short
but also
multiline + Bob->>Alice: Short as well
and also
multiline + `, + { sequence: { messageAlign: 'left' } } + ); + }); + it('should render multi-line messages aligned to the right when configured', () => { + imgSnapshotTest( + ` + sequenceDiagram + Alice->>Bob: I'm short
but also
multiline + Bob->>Alice: Short as well
and also
multiline + `, + { sequence: { messageAlign: 'right' } } + ); + }); }); context('auth width scaling', () => { it('should render long actor descriptions', () => { diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index d83d9dc2bb3..c7666233269 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -230,7 +230,7 @@ const drawNote = function (elem, noteModel) { textObj.fontWeight = conf.noteFontWeight; textObj.anchor = conf.noteAlign; textObj.textMargin = conf.noteMargin; - textObj.valign = conf.noteAlign; + textObj.valign = 'center'; let textElem = drawText(g, textObj); @@ -342,7 +342,7 @@ const drawMessage = function (diagram, msgModel, lineStarty) { textObj.fontSize = conf.messageFontSize; textObj.fontWeight = conf.messageFontWeight; textObj.anchor = conf.messageAlign; - textObj.valign = conf.messageAlign; + textObj.valign = 'center'; textObj.textMargin = conf.wrapPadding; textObj.tspan = false; diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index a00d10169f8..3d9a0bbf257 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -193,7 +193,7 @@ export const drawText = function (elem, textData) { case 'start': textData.x = Math.round(textData.x + textData.textMargin); textData.anchor = 'start'; - textData.dominantBaseline = 'text-after-edge'; + textData.dominantBaseline = 'middle'; textData.alignmentBaseline = 'middle'; break; case 'middle': @@ -207,7 +207,7 @@ export const drawText = function (elem, textData) { case 'end': textData.x = Math.round(textData.x + textData.width - textData.textMargin); textData.anchor = 'end'; - textData.dominantBaseline = 'text-before-edge'; + textData.dominantBaseline = 'middle'; textData.alignmentBaseline = 'middle'; break; } From ce1507c29665145f70511b6ab4dc367e31ab05ac Mon Sep 17 00:00:00 2001 From: mmorel-35 Date: Mon, 18 Jul 2022 07:03:43 +0000 Subject: [PATCH 02/13] chore: update browsers list --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index dadfab51ffa..15beabbe665 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3452,9 +3452,9 @@ camelcase@^6.2.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001359: - version "1.0.30001364" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001364.tgz" - integrity sha512-9O0xzV3wVyX0SlegIQ6knz+okhBB5pE0PC40MNdwcipjwpxoUEHL24uJ+gG42cgklPjfO5ZjZPme9FTSN3QT2Q== + version "1.0.30001367" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz" + integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== caseless@~0.12.0: version "0.12.0" From 4c30e03f1ea1a26292a248794b207e596615593e Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Mon, 18 Jul 2022 16:00:03 +0200 Subject: [PATCH 03/13] Using diagram api to add gitGraph --- cypress/platform/knsv.html | 5 +- docs/Setup.md | 69 ++- src/Diagram.js | 218 ++------ src/assignWithDepth.js | 74 +++ src/config.js | 2 +- src/diagram-api/detectType.js | 100 ++++ src/diagram-api/diagram-orchestration.js | 31 ++ src/diagram-api/diagramAPI.js | 172 +++++- src/diagrams/c4/c4Renderer.js | 9 +- src/diagrams/flowchart/flowRenderer.spec.js | 1 - src/diagrams/git/gitGraphDetector.js | 8 + src/diagrams/mindmap/info.spc.js | 14 + src/diagrams/mindmap/infoDb.js | 34 ++ src/diagrams/mindmap/infoRenderer.js | 59 ++ src/diagrams/mindmap/mindamapDetector.js | 8 + src/diagrams/mindmap/parser/mindamap.jison | 48 ++ src/diagrams/mindmap/styles.js | 3 + src/diagrams/sequence/sequenceDb.js | 9 +- src/diagrams/sequence/sequenceDiagram.spec.js | 523 +++++++++--------- src/diagrams/sequence/sequenceRenderer.js | 3 +- src/diagrams/user-journey/journeyRenderer.js | 1 - src/mermaid.js | 2 +- src/mermaidAPI.js | 49 +- src/mermaidAPI.spec.js | 2 +- src/utils.js | 160 +----- src/utils.spec.js | 43 +- test.js | 5 + 27 files changed, 946 insertions(+), 706 deletions(-) create mode 100644 src/assignWithDepth.js create mode 100644 src/diagram-api/detectType.js create mode 100644 src/diagram-api/diagram-orchestration.js create mode 100644 src/diagrams/git/gitGraphDetector.js create mode 100644 src/diagrams/mindmap/info.spc.js create mode 100644 src/diagrams/mindmap/infoDb.js create mode 100644 src/diagrams/mindmap/infoRenderer.js create mode 100644 src/diagrams/mindmap/mindamapDetector.js create mode 100644 src/diagrams/mindmap/parser/mindamap.jison create mode 100644 src/diagrams/mindmap/styles.js create mode 100644 test.js diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index 8bc9f88e22e..0632913e4be 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -64,7 +64,7 @@ commit commit -
+
sequenceDiagram title: My Sequence Diagram Title accTitle: My Acc Sequence Diagram @@ -283,6 +283,9 @@ class: { // defaultRenderer: 'dagre-d3', htmlLabels: true, + }, + sequence: { + mirrorActors: false, }, // gantt: { axisFormat: '%m/%d/%Y' }, // sequence: { diff --git a/docs/Setup.md b/docs/Setup.md index 04026f5d88f..4a3575d2cf7 100644 --- a/docs/Setup.md +++ b/docs/Setup.md @@ -1401,6 +1401,15 @@ This sets the auto-wrap padding for the diagram (sides only) **Notes:** Default value: 0. +## parse + +### Parameters + +- `text` +- `dia` + +Returns **any** + ## setSiteConfig ## setSiteConfig @@ -1420,14 +1429,6 @@ function _Default value: At default, will mirror Global Config_ Returns **[object][5]** The siteConfig -## parse - -### Parameters - -- `text` - -Returns **any** - ## getSiteConfig ## getSiteConfig @@ -1485,30 +1486,6 @@ options in-place - `options` **any** The potential setConfig parameter -## addDirective - -Pushes in a directive to the configuration - -### Parameters - -- `directive` **[object][5]** The directive to push in - -## reset - -## reset - -| Function | Description | Type | Required | Values | -| -------- | ---------------------------- | ----------- | -------- | ------ | -| reset | Resets currentConfig to conf | Put Request | Required | None | - -## conf - -| Parameter | Description | Type | Required | Values | -| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- | -| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array | - -**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) - ## render Function that renders an svg with a graph from a chart definition. Usage example below. @@ -1537,15 +1514,35 @@ $(function () { Returns **any** -## updateRendererConfigs +## addDirective + +Pushes in a directive to the configuration ### Parameters -- `conf` **any** +- `directive` **[object][5]** The directive to push in -## reinitialize +## reset + +## reset -To be removed +| Function | Description | Type | Required | Values | +| -------- | ---------------------------- | ----------- | -------- | ------ | +| reset | Resets currentConfig to conf | Put Request | Required | None | + +## conf + +| Parameter | Description | Type | Required | Values | +| --------- | -------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- | +| conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array | + +**Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`) + +## updateRendererConfigs + +### Parameters + +- `conf` **any** ## initialize diff --git a/src/Diagram.js b/src/Diagram.js index b1fa1dc4124..a87ed42fb5c 100644 --- a/src/Diagram.js +++ b/src/Diagram.js @@ -1,191 +1,32 @@ -import c4Db from './diagrams/c4/c4Db'; -import c4Renderer from './diagrams/c4/c4Renderer'; -import c4Parser from './diagrams/c4/parser/c4Diagram'; -import classDb from './diagrams/class/classDb'; -import classRenderer from './diagrams/class/classRenderer'; -import classRendererV2 from './diagrams/class/classRenderer-v2'; -import classParser from './diagrams/class/parser/classDiagram'; -import erDb from './diagrams/er/erDb'; -import erRenderer from './diagrams/er/erRenderer'; -import erParser from './diagrams/er/parser/erDiagram'; -import flowDb from './diagrams/flowchart/flowDb'; -import flowRenderer from './diagrams/flowchart/flowRenderer'; -import flowRendererV2 from './diagrams/flowchart/flowRenderer-v2'; -import flowParser from './diagrams/flowchart/parser/flow'; -import ganttDb from './diagrams/gantt/ganttDb'; -import ganttRenderer from './diagrams/gantt/ganttRenderer'; -import ganttParser from './diagrams/gantt/parser/gantt'; -import gitGraphAst from './diagrams/git/gitGraphAst'; -import gitGraphRenderer from './diagrams/git/gitGraphRenderer'; -import gitGraphParser from './diagrams/git/parser/gitGraph'; -import infoDb from './diagrams/info/infoDb'; -import infoRenderer from './diagrams/info/infoRenderer'; -import infoParser from './diagrams/info/parser/info'; -import pieParser from './diagrams/pie/parser/pie'; -import pieDb from './diagrams/pie/pieDb'; -import pieRenderer from './diagrams/pie/pieRenderer'; -import requirementParser from './diagrams/requirement/parser/requirementDiagram'; -import requirementDb from './diagrams/requirement/requirementDb'; -import requirementRenderer from './diagrams/requirement/requirementRenderer'; -import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'; -import sequenceDb from './diagrams/sequence/sequenceDb'; -import sequenceRenderer from './diagrams/sequence/sequenceRenderer'; -import stateParser from './diagrams/state/parser/stateDiagram'; -import stateDb from './diagrams/state/stateDb'; -import stateRenderer from './diagrams/state/stateRenderer'; -import stateRendererV2 from './diagrams/state/stateRenderer-v2'; -import journeyDb from './diagrams/user-journey/journeyDb'; -import journeyRenderer from './diagrams/user-journey/journeyRenderer'; -import journeyParser from './diagrams/user-journey/parser/journey'; import utils from './utils'; import * as configApi from './config'; import { log } from './logger'; - +import { getDiagrams } from './diagram-api/diagramAPI'; +import detectType from './diagram-api/detectType'; class Diagram { type = 'graph'; parser; renderer; db; constructor(txt) { + const diagrams = getDiagrams(); const cnf = configApi.getConfig(); this.txt = txt; - this.type = utils.detectType(txt, cnf); + this.type = detectType(txt, cnf); log.debug('Type ' + this.type); - switch (this.type) { - case 'c4': - this.parser = c4Parser; - this.parser.parser.yy = c4Db; - this.db = c4Db; - this.renderer = c4Renderer; - this.renderer.setConf(cnf.c4); - break; - case 'gitGraph': - this.parser = gitGraphParser; - this.parser.parser.yy = gitGraphAst; - this.db = gitGraphAst; - this.renderer = gitGraphRenderer; - this.txt = this.txt + '\n'; - break; - case 'flowchart': - flowRenderer.setConf(cnf.flowchart); - cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - flowDb.clear(); - flowDb.setGen('gen-1'); - this.parser = flowParser; - this.parser.parser.yy = flowDb; - this.db = flowDb; - this.renderer = flowRenderer; - break; - case 'flowchart-v2': - flowRendererV2.setConf(cnf.flowchart); - cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - flowDb.clear(); - flowDb.setGen('gen-2'); - this.parser = flowParser; - this.parser.parser.yy = flowDb; - this.db = flowDb; - this.renderer = flowRendererV2; - break; - case 'sequenceDiagram': - case 'sequence': - cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - if (cnf.sequenceDiagram) { - // backwards compatibility - sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram)); - console.error( - '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.' - ); - } - this.parser = sequenceParser; - this.parser.parser.yy = sequenceDb; - this.db = sequenceDb; - this.db.setWrap(cnf.wrap); - this.renderer = sequenceRenderer; - this.renderer.setConf(cnf.sequence); - this.txt = this.txt + '\n'; - break; - case 'gantt': - cnf.gantt.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - this.parser = ganttParser; - this.parser.parser.yy = ganttDb; - this.db = ganttDb; - this.renderer = ganttRenderer; - ganttRenderer.setConf(cnf.gantt); - break; - case 'class': - cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - this.parser = classParser; - this.parser.parser.yy = classDb; - this.db = classDb; - this.db.clear(); - this.renderer = classRenderer; - break; - case 'classDiagram': - cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - this.parser = classParser; - this.parser.parser.yy = classDb; - this.db = classDb; - this.db.clear(); - this.renderer = classRendererV2; - break; - case 'state': - cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - this.parser = stateParser; - this.parser.parser.yy = stateDb; - this.db = stateDb; - this.db.clear(); - this.renderer = stateRenderer; - break; - case 'stateDiagram': - cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; - this.parser = stateParser; - this.parser.parser.yy = stateDb; - this.db = stateDb; - this.db.clear(); - this.renderer = stateRendererV2; - break; - case 'info': - log.debug('info info info'); - this.parser = infoParser; - this.parser.parser.yy = infoDb; - this.db = infoDb; - this.renderer = infoRenderer; - break; - case 'pie': - log.debug('pie'); - this.parser = pieParser; - this.parser.parser.yy = pieDb; - this.db = pieDb; - this.renderer = pieRenderer; - break; - case 'er': - log.debug('er'); - this.parser = erParser; - this.parser.parser.yy = erDb; - this.db = erDb; - this.renderer = erRenderer; - break; - case 'journey': - log.debug('Journey'); - journeyRenderer.setConf(cnf.journey); - this.parser = journeyParser; - this.parser.parser.yy = journeyDb; - this.db = journeyDb; - this.db.clear(); - this.renderer = journeyRenderer; - break; - case 'requirement': - case 'requirementDiagram': - log.debug('RequirementDiagram'); - this.parser = requirementParser; - this.parser.parser.yy = requirementDb; - this.db = requirementDb; - this.renderer = requirementRenderer; - break; - default: - log.error('Unkown graphtype'); - throw new Error('Unkown graphtype'); + + // console.log('this.type', this.type, diagrams[this.type]); + // Setup diagram + this.db = diagrams[this.type].db; + this.renderer = diagrams[this.type].renderer; + this.parser = diagrams[this.type].parser; + this.parser.parser.yy = this.db; + if (typeof diagrams[this.type].init === 'function') { + diagrams[this.type].init(cnf); + log.debug('Initialized diagram ' + this.type, cnf); } + this.txt = this.txt + '\n'; + this.parser.parser.yy.graphType = this.type; this.parser.parser.yy.parseError = (str, hash) => { const error = { str, hash }; @@ -193,6 +34,33 @@ class Diagram { }; this.parser.parse(this.txt); } + parse(text) { + var parseEncounteredException = false; + try { + text = text + '\n'; + this.db.clear(); + + this.parser.parse(text); + } catch (error) { + parseEncounteredException = true; + // Is this the correct way to access mermiad's parseError() + // method ? (or global.mermaid.parseError()) ? + if (global.mermaid.parseError) { + if (error.str != undefined) { + // handle case where error string and hash were + // wrapped in object like`const error = { str, hash };` + global.mermaid.parseError(error.str, error.hash); + } else { + // assume it is just error string and pass it on + global.mermaid.parseError(error); + } + } else { + // No mermaid.parseError() handler defined, so re-throw it + throw error; + } + } + return !parseEncounteredException; + } getParser() { return this.parser; } diff --git a/src/assignWithDepth.js b/src/assignWithDepth.js new file mode 100644 index 00000000000..a74c4794573 --- /dev/null +++ b/src/assignWithDepth.js @@ -0,0 +1,74 @@ +/** + * @function assignWithDepth Extends the functionality of {@link ObjectConstructor.assign} with the + * ability to merge arbitrary-depth objects For each key in src with path `k` (recursively) + * performs an Object.assign(dst[`k`], src[`k`]) with a slight change from the typical handling of + * undefined for dst[`k`]: instead of raising an error, dst[`k`] is auto-initialized to {} and + * effectively merged with src[`k`]

Additionally, dissimilar types will not clobber unless the + * config.clobber parameter === true. Example: + * + * ```js + * let config_0 = { foo: { bar: 'bar' }, bar: 'foo' }; + * let config_1 = { foo: 'foo', bar: 'bar' }; + * let result = assignWithDepth(config_0, config_1); + * console.log(result); + * //-> result: { foo: { bar: 'bar' }, bar: 'bar' } + * ``` + * + * Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a + * destructured array of objects and dst is not an array, assignWithDepth will apply each element + * of src to dst in order. + * @param dst + * @param src + * @param config + * @param dst + * @param src + * @param config + * @param dst + * @param src + * @param config + * @param {any} dst - The destination of the merge + * @param {any} src - The source object(s) to merge into destination + * @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth + * to traverse within src and dst for merging - clobber: should dissimilar types clobber (default: + * { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }` + * @returns {any} + */ +const assignWithDepth = function (dst, src, config) { + const { depth, clobber } = Object.assign({ depth: 2, clobber: false }, config); + if (Array.isArray(src) && !Array.isArray(dst)) { + src.forEach((s) => assignWithDepth(dst, s, config)); + return dst; + } else if (Array.isArray(src) && Array.isArray(dst)) { + src.forEach((s) => { + if (dst.indexOf(s) === -1) { + dst.push(s); + } + }); + return dst; + } + if (typeof dst === 'undefined' || depth <= 0) { + if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') { + return Object.assign(dst, src); + } else { + return src; + } + } + if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') { + Object.keys(src).forEach((key) => { + if ( + typeof src[key] === 'object' && + (dst[key] === undefined || typeof dst[key] === 'object') + ) { + if (dst[key] === undefined) { + dst[key] = Array.isArray(src[key]) ? [] : {}; + } + dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber }); + } else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) { + dst[key] = src[key]; + } + }); + } + return dst; +}; + +export default assignWithDepth; diff --git a/src/config.js b/src/config.js index f438318c7cc..59c6c18cbac 100644 --- a/src/config.js +++ b/src/config.js @@ -1,4 +1,4 @@ -import { assignWithDepth } from './utils'; +import assignWithDepth from './assignWithDepth'; import { log } from './logger'; import theme from './themes'; import config from './defaultConfig'; diff --git a/src/diagram-api/detectType.js b/src/diagram-api/detectType.js new file mode 100644 index 00000000000..a5f074e3e15 --- /dev/null +++ b/src/diagram-api/detectType.js @@ -0,0 +1,100 @@ +const directive = + /[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi; +const anyComment = /\s*%%.*\n/gm; +const detectors = {}; +/** + * @function detectType Detects the type of the graph text. Takes into consideration the possible + * existence of an %%init directive + * + * ```mermaid + * %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%% + * graph LR + * a-->b + * b-->c + * c-->d + * d-->e + * e-->f + * f-->g + * g-->h + * ``` + * @param {string} text The text defining the graph + * @param {{ + * class: { defaultRenderer: string } | undefined; + * state: { defaultRenderer: string } | undefined; + * flowchart: { defaultRenderer: string } | undefined; + * }} [cnf] + * @returns {string} A graph definition key + */ +const detectType = function (text, cnf) { + text = text.replace(directive, '').replace(anyComment, '\n'); + if (text.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/)) { + return 'c4'; + } + + if (text.match(/^\s*sequenceDiagram/)) { + return 'sequence'; + } + + if (text.match(/^\s*gantt/)) { + return 'gantt'; + } + if (text.match(/^\s*classDiagram-v2/)) { + return 'classDiagram'; + } + if (text.match(/^\s*classDiagram/)) { + if (cnf && cnf.class && cnf.class.defaultRenderer === 'dagre-wrapper') return 'classDiagram'; + return 'class'; + } + + if (text.match(/^\s*stateDiagram-v2/)) { + return 'stateDiagram'; + } + + if (text.match(/^\s*stateDiagram/)) { + if (cnf && cnf.class && cnf.state.defaultRenderer === 'dagre-wrapper') return 'stateDiagram'; + return 'state'; + } + + // if (text.match(/^\s*gitGraph/)) { + // return 'gitGraph'; + // } + if (text.match(/^\s*flowchart/)) { + return 'flowchart-v2'; + } + + if (text.match(/^\s*info/)) { + return 'info'; + } + if (text.match(/^\s*pie/)) { + return 'pie'; + } + + if (text.match(/^\s*erDiagram/)) { + return 'er'; + } + + if (text.match(/^\s*journey/)) { + return 'journey'; + } + + if (text.match(/^\s*requirement/) || text.match(/^\s*requirementDiagram/)) { + return 'requirement'; + } + if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') + return 'flowchart-v2'; + const k = Object.keys(detectors); + for (let i = 0; i < k.length; i++) { + const key = k[i]; + const dia = detectors[key]; + if (dia && dia.detector(text)) { + return key; + } + } + return 'flowchart'; +}; +export const addDetector = (key, detector) => { + detectors[key] = { + detector, + }; +}; +export default detectType; diff --git a/src/diagram-api/diagram-orchestration.js b/src/diagram-api/diagram-orchestration.js new file mode 100644 index 00000000000..51f1c43db92 --- /dev/null +++ b/src/diagram-api/diagram-orchestration.js @@ -0,0 +1,31 @@ +import { registerDiagram } from './diagramAPI.js'; +// import mindmapDb from '../diagrams/mindmap/mindmapDb'; +// import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer'; +// import mindmapParser from '../diagrams/mindmap/parser/mindmapDiagram'; +// import mindmapDetector from '../diagrams/mindmap/mindmapDetector'; + +import gitGraphDb from '../diagrams/git/gitGraphAst'; +import gitGraphRenderer from '../diagrams/git/gitGraphRenderer'; +import gitGraphParser from '../diagrams/git/parser/gitGraph'; +import gitGraphDetector from '../diagrams/git/gitGraphDetector'; + +// Register mindmap and other built-in diagrams +// registerDiagram( +// 'mindmap', +// mindmapParser, +// mindmapDb, +// mindmapRenderer, +// undefined, +// mindmapRenderer, +// mindmapDetector +// ); +registerDiagram( + 'gitGraph', + gitGraphParser, + gitGraphDb, + gitGraphRenderer, + undefined, + gitGraphDetector +); +const apa = { apa: 1 }; +export default apa; diff --git a/src/diagram-api/diagramAPI.js b/src/diagram-api/diagramAPI.js index a695de5bfaa..176a2bef9de 100644 --- a/src/diagram-api/diagramAPI.js +++ b/src/diagram-api/diagramAPI.js @@ -1,9 +1,175 @@ -const diagrams = {}; +import c4Db from '../diagrams/c4/c4Db'; +import c4Renderer from '../diagrams/c4/c4Renderer'; +import c4Parser from '../diagrams/c4/parser/c4Diagram'; +import classDb from '../diagrams/class/classDb'; +import classRenderer from '../diagrams/class/classRenderer'; +import classRendererV2 from '../diagrams/class/classRenderer-v2'; +import classParser from '../diagrams/class/parser/classDiagram'; +import erDb from '../diagrams/er/erDb'; +import erRenderer from '../diagrams/er/erRenderer'; +import erParser from '../diagrams/er/parser/erDiagram'; +import flowDb from '../diagrams/flowchart/flowDb'; +import flowRenderer from '../diagrams/flowchart/flowRenderer'; +import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2'; +import flowParser from '../diagrams/flowchart/parser/flow'; +import ganttDb from '../diagrams/gantt/ganttDb'; +import ganttRenderer from '../diagrams/gantt/ganttRenderer'; +import ganttParser from '../diagrams/gantt/parser/gantt'; +import infoDb from '../diagrams/info/infoDb'; +import infoRenderer from '../diagrams/info/infoRenderer'; +import infoParser from '../diagrams/info/parser/info'; +import pieParser from '../diagrams/pie/parser/pie'; +import pieDb from '../diagrams/pie/pieDb'; +import pieRenderer from '../diagrams/pie/pieRenderer'; +import requirementParser from '../diagrams/requirement/parser/requirementDiagram'; +import requirementDb from '../diagrams/requirement/requirementDb'; +import requirementRenderer from '../diagrams/requirement/requirementRenderer'; +import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram'; +import sequenceDb from '../diagrams/sequence/sequenceDb'; +import sequenceRenderer from '../diagrams/sequence/sequenceRenderer'; +import stateParser from '../diagrams/state/parser/stateDiagram'; +import stateDb from '../diagrams/state/stateDb'; +import stateRenderer from '../diagrams/state/stateRenderer'; +import stateRendererV2 from '../diagrams/state/stateRenderer-v2'; +import journeyDb from '../diagrams/user-journey/journeyDb'; +import journeyRenderer from '../diagrams/user-journey/journeyRenderer'; +import journeyParser from '../diagrams/user-journey/parser/journey'; +import { addDetector } from './detectType'; -export const registerDiagram = (id, parser, identifier, renderer) => { - diagrams[id] = { parser, identifier, renderer }; +const diagrams = { + c4: { + db: c4Db, + renderer: c4Renderer, + parser: c4Parser, + init: (cnf) => { + c4Renderer.setConf(cnf.c4); + }, + }, + class: { + db: classDb, + renderer: classRenderer, + parser: classParser, + init: (cnf) => { + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + classDb.clear(); + }, + }, + classDiagram: { + db: classDb, + renderer: classRendererV2, + parser: classParser, + init: (cnf) => { + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + classDb.clear(); + }, + }, + er: { + db: erDb, + renderer: erRenderer, + parser: erParser, + }, + flowchart: { + db: flowDb, + renderer: flowRenderer, + parser: flowParser, + init: (cnf) => { + flowRenderer.setConf(cnf.flowchart); + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + flowDb.clear(); + flowDb.setGen('gen-1'); + }, + }, + flowchartV2: { + db: flowDb, + renderer: flowRendererV2, + parser: flowParser, + init: (cnf) => { + flowRendererV2.setConf(cnf.flowchart); + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + flowDb.clear(); + flowDb.setGen('gen-2'); + }, + }, + gantt: { + db: ganttDb, + renderer: ganttRenderer, + parser: ganttParser, + init: (cnf) => { + ganttRenderer.setConf(cnf.gantt); + }, + }, + // git: { + // db: gitGraphAst, + // renderer: gitGraphRenderer, + // parser: gitGraphParser, + // }, + info: { + db: infoDb, + renderer: infoRenderer, + parser: infoParser, + }, + pie: { + db: pieDb, + renderer: pieRenderer, + parser: pieParser, + }, + requirement: { + db: requirementDb, + renderer: requirementRenderer, + parser: requirementParser, + }, + sequence: { + db: sequenceDb, + renderer: sequenceRenderer, + parser: sequenceParser, + init: (cnf) => { + cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + if (cnf.sequenceDiagram) { + // backwards compatibility + sequenceRenderer.setConf(Object.assign(cnf.sequence, cnf.sequenceDiagram)); + console.error( + '`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.' + ); + } + sequenceDb.setWrap(cnf.wrap); + sequenceRenderer.setConf(cnf.sequence); + }, + }, + state: { + db: stateDb, + renderer: stateRenderer, + parser: stateParser, + init: (cnf) => { + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + stateDb.clear(); + }, + }, + stateDiagram: { + db: stateDb, + renderer: stateRendererV2, + parser: stateParser, + init: (cnf) => { + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + stateDb.clear(); + }, + }, + journey: { + db: journeyDb, + renderer: journeyRenderer, + parser: journeyParser, + init: (cnf) => { + journeyRenderer.setConf(cnf.journey); + journeyDb.clear(); + }, + }, +}; +// console.log(sequenceDb); +export const registerDiagram = (id, parser, db, renderer, init, detector) => { + diagrams[id] = { parser, db, renderer, init }; + addDetector(id, detector); }; export const getDiagrams = () => { + // console.log('diagrams', diagrams); return diagrams; }; diff --git a/src/diagrams/c4/c4Renderer.js b/src/diagrams/c4/c4Renderer.js index acd39fa4773..6af59bb928f 100644 --- a/src/diagrams/c4/c4Renderer.js +++ b/src/diagrams/c4/c4Renderer.js @@ -5,13 +5,8 @@ import { parser } from './parser/c4Diagram'; import common from '../common/common'; import c4Db from './c4Db'; import * as configApi from '../../config'; -import utils, { - wrapLabel, - calculateTextWidth, - calculateTextHeight, - assignWithDepth, - configureSvgSize, -} from '../../utils'; +import assignWithDepth from '../../assignWithDepth'; +import { wrapLabel, calculateTextWidth, calculateTextHeight, configureSvgSize } from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; let globalBoundaryMaxX = 0, diff --git a/src/diagrams/flowchart/flowRenderer.spec.js b/src/diagrams/flowchart/flowRenderer.spec.js index 356b3688a93..4e1ce10193e 100644 --- a/src/diagrams/flowchart/flowRenderer.spec.js +++ b/src/diagrams/flowchart/flowRenderer.spec.js @@ -1,6 +1,5 @@ import { addVertices, addEdges } from './flowRenderer'; import { setConfig } from '../../config'; -import Diagram from '../../Diagram'; setConfig({ flowchart: { diff --git a/src/diagrams/git/gitGraphDetector.js b/src/diagrams/git/gitGraphDetector.js new file mode 100644 index 00000000000..3707a330475 --- /dev/null +++ b/src/diagrams/git/gitGraphDetector.js @@ -0,0 +1,8 @@ +const detector = (txt) => { + if (txt.match(/^\s*gitGraph/)) { + return 'gitGraph'; + } + return null; +}; + +export default detector; diff --git a/src/diagrams/mindmap/info.spc.js b/src/diagrams/mindmap/info.spc.js new file mode 100644 index 00000000000..69a969fb134 --- /dev/null +++ b/src/diagrams/mindmap/info.spc.js @@ -0,0 +1,14 @@ +describe('when parsing an info graph it', function () { + var ex; + beforeEach(function () { + ex = require('./parser/info').parser; + ex.yy = require('./infoDb'); + }); + + it('should handle an info definition', function () { + var str = `info + showInfo`; + + ex.parse(str); + }); +}); diff --git a/src/diagrams/mindmap/infoDb.js b/src/diagrams/mindmap/infoDb.js new file mode 100644 index 00000000000..5a324fbb453 --- /dev/null +++ b/src/diagrams/mindmap/infoDb.js @@ -0,0 +1,34 @@ +/** Created by knut on 15-01-14. */ +import { log } from '../../logger'; + +var message = ''; +var info = false; + +export const setMessage = (txt) => { + log.debug('Setting message to: ' + txt); + message = txt; +}; + +export const getMessage = () => { + return message; +}; + +export const setInfo = (inf) => { + info = inf; +}; + +export const getInfo = () => { + return info; +}; + +// export const parseError = (err, hash) => { +// global.mermaidAPI.parseError(err, hash) +// } + +export default { + setMessage, + getMessage, + setInfo, + getInfo, + // parseError +}; diff --git a/src/diagrams/mindmap/infoRenderer.js b/src/diagrams/mindmap/infoRenderer.js new file mode 100644 index 00000000000..cbe3c52f8f0 --- /dev/null +++ b/src/diagrams/mindmap/infoRenderer.js @@ -0,0 +1,59 @@ +/** Created by knut on 14-12-11. */ +import { select } from 'd3'; +import { log } from '../../logger'; +import { getConfig } from '../../config'; + +/** + * Draws a an info picture in the tag with id: id based on the graph definition in text. + * + * @param {any} text + * @param {any} id + * @param {any} version + * @param diagObj + */ +export const draw = (text, id, version, diagObj) => { + try { + // const parser = infoParser.parser; + // parser.yy = db; + log.debug('Renering info diagram\n' + text); + + const securityLevel = getConfig().securityLevel; + // Handle root and Document for when rendering in sanbox mode + let sandboxElement; + if (securityLevel === 'sandbox') { + sandboxElement = select('#i' + id); + } + const root = + securityLevel === 'sandbox' + ? select(sandboxElement.nodes()[0].contentDocument.body) + : select('body'); + const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; + + // Parse the graph definition + // parser.parse(text); + // log.debug('Parsed info diagram'); + // Fetch the default direction, use TD if none was found + const svg = root.select('#' + id); + + const g = svg.append('g'); + + g.append('text') // text label for the x axis + .attr('x', 100) + .attr('y', 40) + .attr('class', 'version') + .attr('font-size', '32px') + .style('text-anchor', 'middle') + .text('v ' + version); + + svg.attr('height', 100); + svg.attr('width', 400); + // svg.attr('viewBox', '0 0 300 150'); + } catch (e) { + log.error('Error while rendering info diagram'); + log.error(e.message); + } +}; + +export default { + draw, +}; diff --git a/src/diagrams/mindmap/mindamapDetector.js b/src/diagrams/mindmap/mindamapDetector.js new file mode 100644 index 00000000000..341e3968cf6 --- /dev/null +++ b/src/diagrams/mindmap/mindamapDetector.js @@ -0,0 +1,8 @@ +const detector = (txt) => { + if (txt.match(/^\s*mindmap/)) { + return 'mindmap'; + } + return null; +}; + +export default detector; diff --git a/src/diagrams/mindmap/parser/mindamap.jison b/src/diagrams/mindmap/parser/mindamap.jison new file mode 100644 index 00000000000..473b63fcfcd --- /dev/null +++ b/src/diagrams/mindmap/parser/mindamap.jison @@ -0,0 +1,48 @@ +/** mermaid + * https://knsv.github.io/mermaid + * (c) 2015 Knut Sveidqvist + * MIT license. + */ +%lex + +%options case-insensitive + +%{ + // Pre-lexer code can go here +%} + +%% + +"info" return 'info' ; +[\s\n\r]+ return 'NL' ; +[\s]+ return 'space'; +"showInfo" return 'showInfo'; +<> return 'EOF' ; +. return 'TXT' ; + +/lex + +%start start + +%% /* language grammar */ + +start +// %{ : info document 'EOF' { return yy; } } + : info document 'EOF' { return yy; } + ; + +document + : /* empty */ + | document line + ; + +line + : statement { } + | 'NL' + ; + +statement + : showInfo { yy.setInfo(true); } + ; + +%% diff --git a/src/diagrams/mindmap/styles.js b/src/diagrams/mindmap/styles.js new file mode 100644 index 00000000000..0b0729813df --- /dev/null +++ b/src/diagrams/mindmap/styles.js @@ -0,0 +1,3 @@ +const getStyles = () => ``; + +export default getStyles; diff --git a/src/diagrams/sequence/sequenceDb.js b/src/diagrams/sequence/sequenceDb.js index 7d68c972380..8ae5fe8f109 100644 --- a/src/diagrams/sequence/sequenceDb.js +++ b/src/diagrams/sequence/sequenceDb.js @@ -140,7 +140,14 @@ export const setWrap = function (wrapSetting) { wrapEnabled = wrapSetting; }; -export const autoWrap = () => wrapEnabled; +export const autoWrap = () => { + // if setWrap has been called, use that value, otherwise use the value from the config + // TODO: refactor, always use the config value let setWrap update the config value + if (typeof wrapEnabled !== 'undefined') { + return wrapEnabled; + } + return configApi.getConfig().sequence.wrap; +}; export const clear = function () { actors = {}; diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js index 5f77c902915..5f09e0e2d2a 100644 --- a/src/diagrams/sequence/sequenceDiagram.spec.js +++ b/src/diagrams/sequence/sequenceDiagram.spec.js @@ -1,9 +1,12 @@ -import sequence from './parser/sequenceDiagram'; -import sequenceDb from './sequenceDb'; +// import sequence from './parser/sequenceDiagram'; +// import sequenceDb from './sequenceDb'; import * as configApi from '../../config'; -import renderer from './sequenceRenderer'; +// import renderer from './sequenceRenderer'; import mermaidAPI from '../../mermaidAPI'; +// import '../../diagram-api/diagramAPI'; import Diagram from '../../Diagram'; + +// console.log('sequenceDiagram', sequenceDb); /** * @param conf * @param key @@ -16,29 +19,33 @@ function addConf(conf, key, value) { return conf; } -const parser = sequence.parser; +// const parser = sequence.parser; +let diagram; describe('when parsing a sequenceDiagram', function () { beforeEach(function () { - parser.yy = sequenceDb; - parser.yy.clear(); + // diagram.db = sequenceDb; + // diagram.db.clear(); + diagram = new Diagram(` +sequenceDiagram +Alice->Bob:Hello Bob, how are you? +Note right of Bob: Bob thinks +Bob-->Alice: I am good thanks!`); + diagram.db.clear(); }); - fit('should handle a sequenceDiagram definition', function () { + it('should handle a sequenceDiagram definition', function () { const str = ` sequenceDiagram Alice->Bob:Hello Bob, how are you? Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; - // const dia = new Diagram(str); - // console.log('Type = ' + dia.type); - - mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + mermaidAPI.parse(str, diagram); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -52,8 +59,8 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); // needs to be rendered for the correct value of visibility autonumbers - expect(parser.yy.showSequenceNumbers()).toBe(false); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + expect(diagram.db.showSequenceNumbers()).toBe(false); }); it('it should show sequence numbers when autonumber is enabled', function () { const str = ` @@ -64,8 +71,8 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); // needs to be rendered for the correct value of visibility autonumbers - expect(parser.yy.showSequenceNumbers()).toBe(true); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + expect(diagram.db.showSequenceNumbers()).toBe(true); }); it('it should handle a sequenceDiagram definition with a title:', function () { const str = ` @@ -76,13 +83,13 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - expect(parser.yy.getAccDescription()).toBe(''); - const messages = parser.yy.getMessages(); - const title = parser.yy.getDiagramTitle(); + expect(diagram.db.getAccDescription()).toBe(''); + const messages = diagram.db.getMessages(); + const title = diagram.db.getDiagramTitle(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -99,13 +106,13 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - expect(parser.yy.getAccDescription()).toBe(''); - const messages = parser.yy.getMessages(); - const title = parser.yy.getDiagramTitle(); + expect(diagram.db.getAccDescription()).toBe(''); + const messages = diagram.db.getMessages(); + const title = diagram.db.getDiagramTitle(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -123,10 +130,10 @@ Alice->Bob:Hello Bob, how are you? `; mermaidAPI.parse(str); - expect(parser.yy.getDiagramTitle()).toBe('Diagram Title'); - expect(parser.yy.getAccTitle()).toBe('This is the title'); - expect(parser.yy.getAccDescription()).toBe('Accessibility Description'); - const messages = parser.yy.getMessages(); + expect(diagram.db.getDiagramTitle()).toBe('Diagram Title'); + expect(diagram.db.getAccTitle()).toBe('This is the title'); + expect(diagram.db.getAccDescription()).toBe('Accessibility Description'); + const messages = diagram.db.getMessages(); }); it('it should handle a sequenceDiagram definition with a accessibility title and multiline description (accDescr)', function () { const str = ` @@ -140,9 +147,9 @@ Alice->Bob:Hello Bob, how are you? `; mermaidAPI.parse(str); - expect(parser.yy.getAccTitle()).toBe('This is the title'); - expect(parser.yy.getAccDescription()).toBe('Accessibility\nDescription'); - const messages = parser.yy.getMessages(); + expect(diagram.db.getAccTitle()).toBe('This is the title'); + expect(diagram.db.getAccDescription()).toBe('Accessibility\nDescription'); + const messages = diagram.db.getMessages(); }); it('it should space in actor names', function () { @@ -152,11 +159,11 @@ Alice->Bob:Hello Bob, how are - you? Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(2); expect(messages[0].from).toBe('Alice'); @@ -169,11 +176,11 @@ Alice-in-Wonderland->Bob:Hello Bob, how are - you? Bob-->Alice-in-Wonderland:I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors['Alice-in-Wonderland'].description).toBe('Alice-in-Wonderland'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(2); expect(messages[0].from).toBe('Alice-in-Wonderland'); @@ -189,13 +196,13 @@ B-->A: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(Object.keys(actors)).toEqual(['A', 'B']); expect(actors.A.description).toBe('Alice'); expect(actors.B.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(2); expect(messages[0].from).toBe('A'); expect(messages[1].from).toBe('B'); @@ -215,7 +222,7 @@ sequenceDiagram mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(Object.keys(actors)).toEqual(['Alice', 'Bob', 'John', 'Mandy', 'Joan']); expect(actors.Alice.description).toBe('Alice2'); expect(actors.Alice.type).toBe('actor'); @@ -223,7 +230,7 @@ sequenceDiagram expect(actors.John.type).toBe('participant'); expect(actors.Joan.type).toBe('participant'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(5); expect(messages[0].from).toBe('Alice'); expect(messages[4].to).toBe('Joan'); @@ -238,12 +245,12 @@ B-->A: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(Object.keys(actors)).toEqual(['A', 'B']); expect(actors.A.description).toBe('Alice'); expect(actors.B.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(2); expect(messages[0].from).toBe('A'); expect(messages[1].from).toBe('B'); @@ -254,14 +261,14 @@ sequenceDiagram Alice-xBob:Hello Bob, how are you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS); + expect(messages[0].type).toBe(diagram.db.LINETYPE.SOLID_CROSS); }); it('it should handle in async dotted messages', function () { const str = ` @@ -269,14 +276,14 @@ sequenceDiagram Alice--xBob:Hello Bob, how are you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED_CROSS); }); it('it should handle in sync messages', function () { const str = ` @@ -284,14 +291,14 @@ sequenceDiagram Alice-)Bob:Hello Bob, how are you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_POINT); + expect(messages[0].type).toBe(diagram.db.LINETYPE.SOLID_POINT); }); it('it should handle in sync dotted messages', function () { const str = ` @@ -299,14 +306,14 @@ sequenceDiagram Alice--)Bob:Hello Bob, how are you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_POINT); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED_POINT); }); it('it should handle in arrow messages', function () { const str = ` @@ -314,27 +321,27 @@ sequenceDiagram Alice->>Bob:Hello Bob, how are you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID); + expect(messages[0].type).toBe(diagram.db.LINETYPE.SOLID); }); it('it should handle in arrow messages', function () { const str = 'sequenceDiagram\n' + 'Alice-->>Bob:Hello Bob, how are you?'; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(1); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED); }); it('it should handle actor activation', function () { const str = ` @@ -345,18 +352,18 @@ Bob-->>Alice:Hello Alice, I'm fine and you? deactivate Bob`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(4); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START); expect(messages[1].from.actor).toBe('Bob'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END); + expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END); expect(messages[3].from.actor).toBe('Bob'); }); it('it should handle actor one line notation activation', function () { @@ -366,18 +373,18 @@ deactivate Bob`; Bob-->>- Alice:Hello Alice, I'm fine and you?`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(4); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START); expect(messages[1].from.actor).toBe('Bob'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END); + expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_END); expect(messages[3].from.actor).toBe('Bob'); }); it('it should handle stacked activations', function () { @@ -389,22 +396,22 @@ deactivate Bob`; Carol->>- Bob:Oh Bob, I'm so happy to be here!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(8); - expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START); + expect(messages[0].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[1].type).toBe(diagram.db.LINETYPE.ACTIVE_START); expect(messages[1].from.actor).toBe('Bob'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED); - expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_START); + expect(messages[2].type).toBe(diagram.db.LINETYPE.DOTTED); + expect(messages[3].type).toBe(diagram.db.LINETYPE.ACTIVE_START); expect(messages[3].from.actor).toBe('Carol'); - expect(messages[5].type).toBe(parser.yy.LINETYPE.ACTIVE_END); + expect(messages[5].type).toBe(diagram.db.LINETYPE.ACTIVE_END); expect(messages[5].from.actor).toBe('Bob'); - expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END); + expect(messages[7].type).toBe(diagram.db.LINETYPE.ACTIVE_END); expect(messages[7].from.actor).toBe('Carol'); }); it('it should handle fail parsing when activating an inactive participant', function () { @@ -442,11 +449,11 @@ deactivate Bob`; Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -463,11 +470,11 @@ deactivate Bob`; `; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -478,11 +485,11 @@ deactivate Bob`; sequenceDiagram;Alice->Bob: Hello Bob, how are you?;Note right of Bob: Bob thinks;Bob-->Alice: I am good thanks!;`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -498,11 +505,11 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -518,11 +525,11 @@ Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); expect(messages[0].from).toBe('Alice'); @@ -543,11 +550,11 @@ Note right of John: Rational thoughts
prevail... Bob-->John: Jolly good!`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(8); expect(messages[0].from).toBe('Alice'); @@ -572,13 +579,13 @@ note right of 1: multiline
text mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors['1'].description).toBe('multiline
text'); expect(actors['2'].description).toBe('multiline
text'); expect(actors['3'].description).toBe('multiline
text'); expect(actors['4'].description).toBe('multiline
text'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[0].message).toBe('multiline
text'); expect(messages[1].message).toBe('multiline
text'); expect(messages[2].message).toBe('multiline
text'); @@ -607,7 +614,7 @@ note right of 1:nowrap: multiline
text mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[0].message).toBe('single-line text'); expect(messages[1].message).toBe('single-line text'); expect(messages[2].message).toBe('single-line text'); @@ -642,7 +649,7 @@ note right of 3:wrap: multiline
text mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[0].message).toBe('single-line text'); expect(messages[1].message).toBe('single-line text'); expect(messages[2].message).toBe('multiline
text'); @@ -663,7 +670,7 @@ note right of 2: single-line text mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[0].message).toBe('single-line text'); expect(messages[1].message).toBe('single-line text'); expect(messages[0].wrap).toBe(false); @@ -678,7 +685,7 @@ Note over Bob: Bob thinks mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].from).toBe('Bob'); expect(messages[1].to).toBe('Bob'); }); @@ -692,7 +699,7 @@ Note over Bob,Alice: resolution mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].from).toBe('Alice'); expect(messages[1].to).toBe('Bob'); expect(messages[2].from).toBe('Bob'); @@ -711,11 +718,11 @@ Bob-->Alice: I am good thanks! end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(5); expect(messages[0].from).toBe('Alice'); @@ -733,16 +740,16 @@ end`; `; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); - expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START); + const messages = diagram.db.getMessages(); + expect(messages[1].type).toEqual(diagram.db.LINETYPE.RECT_START); expect(messages[1].message).toBe('rgb(200, 255, 200)'); - expect(messages[2].type).toEqual(parser.yy.LINETYPE.NOTE); - expect(messages[3].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN); - expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END); + expect(messages[2].type).toEqual(diagram.db.LINETYPE.NOTE); + expect(messages[3].type).toEqual(diagram.db.LINETYPE.DOTTED_OPEN); + expect(messages[4].type).toEqual(diagram.db.LINETYPE.RECT_END); }); it('it should allow for nested rects', function () { @@ -758,19 +765,19 @@ end`; end `; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); - expect(messages[1].type).toEqual(parser.yy.LINETYPE.RECT_START); + const messages = diagram.db.getMessages(); + expect(messages[1].type).toEqual(diagram.db.LINETYPE.RECT_START); expect(messages[1].message).toBe('rgb(200, 255, 200)'); - expect(messages[2].type).toEqual(parser.yy.LINETYPE.RECT_START); + expect(messages[2].type).toEqual(diagram.db.LINETYPE.RECT_START); expect(messages[2].message).toBe('rgb(0, 0, 0)'); - expect(messages[3].type).toEqual(parser.yy.LINETYPE.NOTE); - expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END); - expect(messages[5].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN); - expect(messages[6].type).toEqual(parser.yy.LINETYPE.RECT_END); + expect(messages[3].type).toEqual(diagram.db.LINETYPE.NOTE); + expect(messages[4].type).toEqual(diagram.db.LINETYPE.RECT_END); + expect(messages[5].type).toEqual(diagram.db.LINETYPE.DOTTED_OPEN); + expect(messages[6].type).toEqual(diagram.db.LINETYPE.RECT_END); }); it('it should handle opt statements', function () { const str = ` @@ -785,11 +792,11 @@ Bob-->Alice: I am good thanks! end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(5); expect(messages[0].from).toBe('Alice'); @@ -810,12 +817,12 @@ Bob-->Alice: Feel sick... end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); actors.Bob.description = 'Bob'; - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(7); expect(messages[0].from).toBe('Alice'); @@ -837,16 +844,16 @@ else default Bob-->Alice: :-) end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(9); expect(messages[1].from).toBe('Bob'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.ALT_START); + expect(messages[2].type).toBe(diagram.db.LINETYPE.ALT_START); expect(messages[3].from).toBe('Bob'); - expect(messages[4].type).toBe(parser.yy.LINETYPE.ALT_ELSE); + expect(messages[4].type).toBe(diagram.db.LINETYPE.ALT_ELSE); expect(messages[5].from).toBe('Bob'); - expect(messages[6].type).toBe(parser.yy.LINETYPE.ALT_ELSE); + expect(messages[6].type).toBe(diagram.db.LINETYPE.ALT_ELSE); expect(messages[7].from).toBe('Bob'); - expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END); + expect(messages[8].type).toBe(diagram.db.LINETYPE.ALT_END); }); it('it should handle critical statements without options', function () { const str = ` @@ -856,17 +863,17 @@ sequenceDiagram end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Service.description).toBe('Service'); expect(actors.DB.description).toBe('DB'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(3); - expect(messages[0].type).toBe(parser.yy.LINETYPE.CRITICAL_START); + expect(messages[0].type).toBe(diagram.db.LINETYPE.CRITICAL_START); expect(messages[1].from).toBe('Service'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.CRITICAL_END); + expect(messages[2].type).toBe(diagram.db.LINETYPE.CRITICAL_END); }); it('it should handle critical statements with options', function () { const str = ` @@ -880,21 +887,21 @@ sequenceDiagram end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Service.description).toBe('Service'); expect(actors.DB.description).toBe('DB'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(7); - expect(messages[0].type).toBe(parser.yy.LINETYPE.CRITICAL_START); + expect(messages[0].type).toBe(diagram.db.LINETYPE.CRITICAL_START); expect(messages[1].from).toBe('Service'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.CRITICAL_OPTION); + expect(messages[2].type).toBe(diagram.db.LINETYPE.CRITICAL_OPTION); expect(messages[3].from).toBe('Service'); - expect(messages[4].type).toBe(parser.yy.LINETYPE.CRITICAL_OPTION); + expect(messages[4].type).toBe(diagram.db.LINETYPE.CRITICAL_OPTION); expect(messages[5].from).toBe('Service'); - expect(messages[6].type).toBe(parser.yy.LINETYPE.CRITICAL_END); + expect(messages[6].type).toBe(diagram.db.LINETYPE.CRITICAL_END); }); it('it should handle break statements', function () { const str = ` @@ -907,19 +914,19 @@ sequenceDiagram API-->BillingService: Start billing process`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Consumer.description).toBe('Consumer'); expect(actors.API.description).toBe('API'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(6); expect(messages[0].from).toBe('Consumer'); expect(messages[1].from).toBe('API'); - expect(messages[2].type).toBe(parser.yy.LINETYPE.BREAK_START); + expect(messages[2].type).toBe(diagram.db.LINETYPE.BREAK_START); expect(messages[3].from).toBe('API'); - expect(messages[4].type).toBe(parser.yy.LINETYPE.BREAK_END); + expect(messages[4].type).toBe(diagram.db.LINETYPE.BREAK_END); expect(messages[5].from).toBe('API'); }); it('it should handle par statements a sequenceDiagram', function () { @@ -937,12 +944,12 @@ Bob-->>Alice: It's good! end`; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.Alice.description).toBe('Alice'); expect(actors.Bob.description).toBe('Bob'); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages.length).toBe(10); expect(messages[0].message).toBe('Parallel one'); @@ -954,7 +961,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[0].message).toBe('-:<>,'); }); it('it should handle special characters in notes', function () { @@ -965,7 +972,7 @@ Note right of Bob: -:<>,;# comment`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe('-:<>,'); }); it('it should handle special characters in loop', function () { @@ -978,7 +985,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe('-:<>,'); }); it('it should handle special characters in opt', function () { @@ -991,7 +998,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe('-:<>,'); }); it('it should handle special characters in alt', function () { @@ -1006,7 +1013,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe('-:<>,'); expect(messages[3].message).toBe(',<>:-'); }); @@ -1022,7 +1029,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe('-:<>,'); expect(messages[3].message).toBe(',<>:-'); }); @@ -1036,7 +1043,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe(''); expect(messages[2].message).toBe('I am good thanks!'); }); @@ -1050,7 +1057,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe(''); expect(messages[2].message).toBe('I am good thanks!'); }); @@ -1065,7 +1072,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe(''); expect(messages[2].message).toBe('I am good thanks!'); expect(messages[3].message).toBe(''); @@ -1082,7 +1089,7 @@ end`; mermaidAPI.parse(str); - const messages = parser.yy.getMessages(); + const messages = diagram.db.getMessages(); expect(messages[1].message).toBe(''); expect(messages[2].message).toBe('I am good thanks!'); expect(messages[3].message).toBe(''); @@ -1104,7 +1111,7 @@ link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com `; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.a.links['Repo']).toBe('https://repo.contoso.com/'); expect(actors.b.links['Repo']).toBe(undefined); expect(actors.a.links['Dashboard']).toBe('https://dashboard.contoso.com/'); @@ -1128,7 +1135,7 @@ properties b: {"class": "external-service-actor", "icon": "@computer"} `; mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(actors.a.properties['class']).toBe('internal-service-actor'); expect(actors.b.properties['class']).toBe('external-service-actor'); expect(actors.a.properties['icon']).toBe('@clock'); @@ -1158,48 +1165,48 @@ describe('when checking the bounds in a sequenceDiagram', function () { let conf; beforeEach(function () { mermaidAPI.reset(); - parser.yy = sequenceDb; - parser.yy.clear(); - renderer.bounds.init(); - conf = parser.yy.getConfig(); + // diagram.db = sequenceDb; + // diagram.db.clear(); + diagram.renderer.bounds.init(); + conf = diagram.db.getConfig(); }); it('it should handle a simple bound call', function () { - renderer.bounds.insert(100, 100, 200, 200); + diagram.renderer.bounds.insert(100, 100, 200, 200); - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(100); expect(bounds.starty).toBe(100); expect(bounds.stopx).toBe(200); expect(bounds.stopy).toBe(200); }); it('it should handle an expanding bound', function () { - renderer.bounds.insert(100, 100, 200, 200); - renderer.bounds.insert(25, 50, 300, 400); + diagram.renderer.bounds.insert(100, 100, 200, 200); + diagram.renderer.bounds.insert(25, 50, 300, 400); - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(25); expect(bounds.starty).toBe(50); expect(bounds.stopx).toBe(300); expect(bounds.stopy).toBe(400); }); it('it should handle inserts within the bound without changing the outer bounds', function () { - renderer.bounds.insert(100, 100, 200, 200); - renderer.bounds.insert(25, 50, 300, 400); - renderer.bounds.insert(125, 150, 150, 200); + diagram.renderer.bounds.insert(100, 100, 200, 200); + diagram.renderer.bounds.insert(25, 50, 300, 400); + diagram.renderer.bounds.insert(125, 150, 150, 200); - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(25); expect(bounds.starty).toBe(50); expect(bounds.stopx).toBe(300); expect(bounds.stopy).toBe(400); }); it('it should handle a loop without expanding the area', function () { - renderer.bounds.insert(25, 50, 300, 400); - renderer.bounds.verticalPos = 150; - renderer.bounds.newLoop(); - renderer.bounds.insert(125, 150, 150, 200); + diagram.renderer.bounds.insert(25, 50, 300, 400); + diagram.renderer.bounds.verticalPos = 150; + diagram.renderer.bounds.newLoop(); + diagram.renderer.bounds.insert(125, 150, 150, 200); - const loop = renderer.bounds.endLoop(); + const loop = diagram.renderer.bounds.endLoop(); expect(loop.startx).toBe(125 - conf.boxMargin); expect(loop.starty).toBe(150 - conf.boxMargin); @@ -1207,7 +1214,7 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(loop.stopy).toBe(200 + conf.boxMargin); // Check bounds of first loop - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(25); expect(bounds.starty).toBe(50); @@ -1215,14 +1222,14 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(bounds.stopy).toBe(400); }); it('it should handle multiple loops withtout expanding the bounds', function () { - renderer.bounds.insert(100, 100, 1000, 1000); - renderer.bounds.verticalPos = 200; - renderer.bounds.newLoop(); - renderer.bounds.newLoop(); - renderer.bounds.insert(200, 200, 300, 300); + diagram.renderer.bounds.insert(100, 100, 1000, 1000); + diagram.renderer.bounds.verticalPos = 200; + diagram.renderer.bounds.newLoop(); + diagram.renderer.bounds.newLoop(); + diagram.renderer.bounds.insert(200, 200, 300, 300); // Check bounds of first loop - let loop = renderer.bounds.endLoop(); + let loop = diagram.renderer.bounds.endLoop(); expect(loop.startx).toBe(200 - conf.boxMargin); expect(loop.starty).toBe(200 - conf.boxMargin); @@ -1230,7 +1237,7 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(loop.stopy).toBe(300 + conf.boxMargin); // Check bounds of second loop - loop = renderer.bounds.endLoop(); + loop = diagram.renderer.bounds.endLoop(); expect(loop.startx).toBe(200 - 2 * conf.boxMargin); expect(loop.starty).toBe(200 - 2 * conf.boxMargin); @@ -1238,7 +1245,7 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(loop.stopy).toBe(300 + 2 * conf.boxMargin); // Check bounds of first loop - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(100); expect(bounds.starty).toBe(100); @@ -1246,12 +1253,12 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(bounds.stopy).toBe(1000); }); it('it should handle a loop that expands the area', function () { - renderer.bounds.insert(100, 100, 200, 200); - renderer.bounds.verticalPos = 200; - renderer.bounds.newLoop(); - renderer.bounds.insert(50, 50, 300, 300); + diagram.renderer.bounds.insert(100, 100, 200, 200); + diagram.renderer.bounds.verticalPos = 200; + diagram.renderer.bounds.newLoop(); + diagram.renderer.bounds.insert(50, 50, 300, 300); - const loop = renderer.bounds.endLoop(); + const loop = diagram.renderer.bounds.endLoop(); expect(loop.startx).toBe(50 - conf.boxMargin); expect(loop.starty).toBe(50 - conf.boxMargin); @@ -1259,7 +1266,7 @@ describe('when checking the bounds in a sequenceDiagram', function () { expect(loop.stopy).toBe(300 + conf.boxMargin); // Check bounds after the loop - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(loop.startx); expect(bounds.starty).toBe(loop.starty); @@ -1289,6 +1296,8 @@ describe('when rendering a sequenceDiagram APA', function () { let conf; beforeEach(function () { mermaidAPI.reset(); + + // }); conf = { diagramMarginX: 50, diagramMarginY: 10, @@ -1304,9 +1313,12 @@ describe('when rendering a sequenceDiagram APA', function () { mirrorActors: false, }; configApi.setSiteConfig({ logLevel: 5, sequence: conf }); - parser.yy = sequenceDb; - parser.yy.clear(); - // conf = parser.yy.getConfig(); + diagram = new Diagram(` +sequenceDiagram +Alice->Bob:Hello Bob, how are you? +Note right of Bob: Bob thinks +Bob-->Alice: I am good thanks!`); + diagram.db.clear(); }); ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) { it(` @@ -1315,12 +1327,12 @@ it should handle one actor, when textPlacement is ${textPlacement}`, function () sequenceDiagram participant Alice`; - mermaidAPI.reinitialize({ sequence: { textPlacement: textPlacement } }); + // mermaidAPI.reinitialize({ sequence: { textPlacement: textPlacement } }); mermaidAPI.parse(str); - // renderer.setConf(mermaidAPI.getConfig().sequence); - renderer.draw(str, 'tst'); + // diagram.renderer.setConf(mermaidAPI.getConfig().sequence); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds } = renderer.bounds.getBounds(); + const { bounds } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width); @@ -1337,7 +1349,7 @@ participant Alice mermaidAPI.parse(str); - const actors = parser.yy.getActors(); + const actors = diagram.db.getActors(); expect(Object.keys(actors)).toEqual(['Alice']); }); it('it should handle one actor and a centered note', function () { @@ -1349,9 +1361,9 @@ Note over Alice: Alice thinks expect(mermaidAPI.getConfig().sequence.mirrorActors).toBeFalsy(); mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width); @@ -1364,10 +1376,10 @@ sequenceDiagram participant Alice Note left of Alice: Alice thinks`; - mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + mermaidAPI.parse(str, diagram); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width); @@ -1381,9 +1393,9 @@ participant Alice Note right of Alice: Alice thinks`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width / 2 + conf.actorMargin / 2 + conf.width); @@ -1396,9 +1408,9 @@ sequenceDiagram Alice->Bob: Hello Bob, how are you?`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin); @@ -1411,9 +1423,9 @@ sequenceDiagram Alice->Bob: Hello Bob, how are you?`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); const mermaid = mermaidAPI.getConfig(); expect(mermaid.logLevel).toBe(0); expect(bounds.startx).toBe(0); @@ -1431,10 +1443,10 @@ wrap Alice->Bob: Hello Bob, how are you?`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const msgs = parser.yy.getMessages(); - const { bounds, models } = renderer.bounds.getBounds(); + const msgs = diagram.db.getMessages(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); const mermaid = mermaidAPI.getConfig(); expect(mermaid.logLevel).toBe(0); expect(bounds.startx).toBe(0); @@ -1452,9 +1464,9 @@ Note over Bob,Alice: Looks back `; // mermaidAPI.initialize({logLevel:0}) mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin); @@ -1467,9 +1479,9 @@ Alice->Bob: Hello Bob, how are you? Bob->Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin); @@ -1483,9 +1495,9 @@ Note right of Bob: Bob thinks Bob->Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); @@ -1502,9 +1514,9 @@ Note left of Alice: Bob thinks Bob->Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); @@ -1519,10 +1531,10 @@ Note left of Alice: Bob thinks Bob->>Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); - const msgs = parser.yy.getMessages(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); + const msgs = diagram.db.getMessages(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); expect(msgs[0].wrap).toBe(true); @@ -1540,10 +1552,10 @@ Note left of Alice: Bob thinks Bob->>Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); - const msgs = parser.yy.getMessages(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); + const msgs = diagram.db.getMessages(); const mermaid = mermaidAPI.getConfig(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); @@ -1563,10 +1575,10 @@ Note left of Alice: Bob thinks Bob->>Alice: Fine!`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); - const msgs = parser.yy.getMessages(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); + const msgs = diagram.db.getMessages(); const mermaid = mermaidAPI.getConfig(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); @@ -1583,11 +1595,12 @@ sequenceDiagram Alice->>Bob: Hello Bob, how are you? If you are not available right now, I can leave you a message. Please get back to me as soon as you can! Note left of Alice: Bob thinks Bob->>Alice: Fine!`; - mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + // mermaidAPI.initialize({ logLevel: 0 }); + mermaidAPI.parse(str, diagram); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); - const msgs = parser.yy.getMessages(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); + const msgs = diagram.db.getMessages(); const mermaid = mermaidAPI.getConfig(); expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2); expect(bounds.starty).toBe(0); @@ -1608,9 +1621,9 @@ loop Cheers Bob->Alice: Fine! end`; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); @@ -1626,8 +1639,8 @@ end`; end `; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); - const { bounds, models } = renderer.bounds.getBounds(); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); @@ -1661,23 +1674,23 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio let conf; beforeEach(function () { mermaidAPI.reset(); - parser.yy = sequenceDb; - parser.yy.clear(); - conf = parser.yy.getConfig(); - renderer.bounds.init(); + // diagram.db = sequenceDb; + diagram.db.clear(); + conf = diagram.db.getConfig(); + diagram.renderer.bounds.init(); }); ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) { it('it should handle one actor, when textPlacement is' + textPlacement, function () { mermaidAPI.initialize(addConf(conf, 'textPlacement', textPlacement)); - renderer.bounds.init(); + diagram.renderer.bounds.init(); const str = ` sequenceDiagram participant Alice`; - renderer.bounds.init(); + diagram.renderer.bounds.init(); mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); expect(bounds.startx).toBe(0); expect(bounds.starty).toBe(0); expect(bounds.stopx).toBe(conf.width); @@ -1705,10 +1718,10 @@ describe('when rendering a sequenceDiagram with directives', function () { let conf; beforeEach(function () { mermaidAPI.reset(); - parser.yy = sequenceDb; - parser.yy.clear(); - conf = parser.yy.getConfig(); - renderer.bounds.init(); + // diagram.db = sequenceDb; + diagram.db.clear(); + conf = diagram.db.getConfig(); + diagram.renderer.bounds.init(); }); it('it should handle one actor, when theme is dark and logLevel is 1 DX1', function () { @@ -1719,12 +1732,12 @@ sequenceDiagram participant Alice `; - renderer.bounds.init(); + diagram.renderer.bounds.init(); mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); const mermaid = mermaidAPI.getConfig(); expect(mermaid.theme).toBe('dark'); expect(mermaid.logLevel).toBe(1); @@ -1743,9 +1756,9 @@ participant Alice `; mermaidAPI.parse(str); - renderer.draw(str, 'tst'); + diagram.renderer.draw(str, 'tst', '1.2.3', diagram); - const { bounds, models } = renderer.bounds.getBounds(); + const { bounds, models } = diagram.renderer.bounds.getBounds(); const mermaid = mermaidAPI.getConfig(); expect(mermaid.logLevel).toBe(3); expect(bounds.startx).toBe(0); @@ -1763,9 +1776,9 @@ Alice->Bob:Hello Bob, how are you? Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; - mermaidAPI.parse(str1); - renderer.draw(str1, 'tst'); // needs to be rendered for the correct value of visibility autonumbers - expect(parser.yy.showSequenceNumbers()).toBe(true); + mermaidAPI.parse(str1, diagram); + diagram.renderer.draw(str1, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility autonumbers + expect(diagram.db.showSequenceNumbers()).toBe(true); const str2 = ` sequenceDiagram @@ -1773,8 +1786,8 @@ Alice->Bob:Hello Bob, how are you? Note right of Bob: Bob thinks Bob-->Alice: I am good thanks!`; - mermaidAPI.parse(str2); - renderer.draw(str2, 'tst'); - expect(parser.yy.showSequenceNumbers()).toBe(false); + mermaidAPI.parse(str2, diagram); + diagram.renderer.draw(str2, 'tst', '1.2.3', diagram); + expect(diagram.db.showSequenceNumbers()).toBe(false); }); }); diff --git a/src/diagrams/sequence/sequenceRenderer.js b/src/diagrams/sequence/sequenceRenderer.js index 809e3164f77..46d48b05876 100644 --- a/src/diagrams/sequence/sequenceRenderer.js +++ b/src/diagrams/sequence/sequenceRenderer.js @@ -5,7 +5,8 @@ import { log } from '../../logger'; import common from '../common/common'; // import sequenceDb from './sequenceDb'; import * as configApi from '../../config'; -import utils, { assignWithDepth, configureSvgSize } from '../../utils'; +import assignWithDepth from '../../assignWithDepth'; +import utils, { configureSvgSize } from '../../utils'; import addSVGAccessibilityFields from '../../accessibility'; let conf = {}; diff --git a/src/diagrams/user-journey/journeyRenderer.js b/src/diagrams/user-journey/journeyRenderer.js index c8ad6278c06..79424cfef68 100644 --- a/src/diagrams/user-journey/journeyRenderer.js +++ b/src/diagrams/user-journey/journeyRenderer.js @@ -69,7 +69,6 @@ export const draw = function (text, id, version, diagObj) { svgDraw.initGraphics(diagram); const tasks = diagObj.db.getTasks(); - console.log('text and tasks', text, tasks); const title = diagObj.db.getDiagramTitle(); const actorNames = diagObj.db.getActors(); diff --git a/src/mermaid.js b/src/mermaid.js index 3ea510a7f4f..a708554a8d1 100644 --- a/src/mermaid.js +++ b/src/mermaid.js @@ -209,7 +209,7 @@ const setParseErrorHandler = function (newParseErrorHandler) { const mermaid = { startOnLoad: true, htmlLabels: true, - + diagrams: {}, mermaidAPI, parse: mermaidAPI != undefined ? mermaidAPI.parse : null, render: mermaidAPI != undefined ? mermaidAPI.render : null, diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 7bd06e04ca3..9c45a2bf2ec 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -19,56 +19,27 @@ import { select } from 'd3'; import { compile, serialize, stringify } from 'stylis'; import pkg from '../package.json'; import * as configApi from './config'; -import c4Db from './diagrams/c4/c4Db'; -import c4Renderer from './diagrams/c4/c4Renderer'; -import c4Parser from './diagrams/c4/parser/c4Diagram'; +import apa from './diagram-api/diagram-orchestration'; import classDb from './diagrams/class/classDb'; -import classRenderer from './diagrams/class/classRenderer'; -import classRendererV2 from './diagrams/class/classRenderer-v2'; -import classParser from './diagrams/class/parser/classDiagram'; -import erDb from './diagrams/er/erDb'; -import erRenderer from './diagrams/er/erRenderer'; -import erParser from './diagrams/er/parser/erDiagram'; import flowDb from './diagrams/flowchart/flowDb'; import flowRenderer from './diagrams/flowchart/flowRenderer'; import flowRendererV2 from './diagrams/flowchart/flowRenderer-v2'; -import flowParser from './diagrams/flowchart/parser/flow'; import ganttDb from './diagrams/gantt/ganttDb'; import ganttRenderer from './diagrams/gantt/ganttRenderer'; -import ganttParser from './diagrams/gantt/parser/gantt'; -import gitGraphAst from './diagrams/git/gitGraphAst'; -import gitGraphRenderer from './diagrams/git/gitGraphRenderer'; -import gitGraphParser from './diagrams/git/parser/gitGraph'; -import infoDb from './diagrams/info/infoDb'; -import infoRenderer from './diagrams/info/infoRenderer'; -import infoParser from './diagrams/info/parser/info'; -import pieParser from './diagrams/pie/parser/pie'; -import pieDb from './diagrams/pie/pieDb'; -import pieRenderer from './diagrams/pie/pieRenderer'; -import addSVGAccessibilityFields from './diagrams/pie/pieRenderer'; -import requirementParser from './diagrams/requirement/parser/requirementDiagram'; -import requirementDb from './diagrams/requirement/requirementDb'; -import requirementRenderer from './diagrams/requirement/requirementRenderer'; -import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'; -import sequenceDb from './diagrams/sequence/sequenceDb'; import sequenceRenderer from './diagrams/sequence/sequenceRenderer'; -import stateParser from './diagrams/state/parser/stateDiagram'; -import stateDb from './diagrams/state/stateDb'; import stateRenderer from './diagrams/state/stateRenderer'; import stateRendererV2 from './diagrams/state/stateRenderer-v2'; -import journeyDb from './diagrams/user-journey/journeyDb'; import journeyRenderer from './diagrams/user-journey/journeyRenderer'; -import journeyParser from './diagrams/user-journey/parser/journey'; import Diagram from './Diagram'; import errorRenderer from './errorRenderer'; import { attachFunctions } from './interactionDb'; import { log, setLogLevel } from './logger'; import getStyles from './styles'; import theme from './themes'; -import utils, { directiveSanitizer, assignWithDepth, sanitizeCss } from './utils'; +import utils, { directiveSanitizer } from './utils'; +import assignWithDepth from './assignWithDepth'; import DOMPurify from 'dompurify'; import mermaid from './mermaid'; - /** * @param text * @param dia @@ -77,20 +48,9 @@ import mermaid from './mermaid'; function parse(text, dia) { var parseEncounteredException = false; try { - text = text + '\n'; const diag = dia ? dia : new Diagram(text); diag.db.clear(); - const cnf = configApi.getConfig(); - let parser = diag.parser; - - log.debug('Type ' + diag.type); - parser.parser.yy.graphType = diag.type; - parser.parser.yy.parseError = (str, hash) => { - const error = { str, hash }; - throw error; - }; - - parser.parse(text); + return diag.parse(text); } catch (error) { parseEncounteredException = true; // Is this the correct way to access mermiad's parseError() @@ -290,6 +250,7 @@ const render = function (id, _txt, cb, container) { txt = encodeEntities(txt); + // Imortant that we do not create the diagram until after the directives have been included const diag = new Diagram(txt); // Get the tmp element containing the the svg const element = root.select('#d' + id).node(); diff --git a/src/mermaidAPI.spec.js b/src/mermaidAPI.spec.js index 74b1be0b5b7..e4c2d168daf 100644 --- a/src/mermaidAPI.spec.js +++ b/src/mermaidAPI.spec.js @@ -1,6 +1,6 @@ import mermaid from './mermaid'; import mermaidAPI from './mermaidAPI'; -import { assignWithDepth } from './utils'; +import assignWithDepth from './assignWithDepth'; describe('when using mermaidAPI and ', function () { describe('doing initialize ', function () { diff --git a/src/utils.js b/src/utils.js index 0d2b4392ce1..db45ab9f623 100644 --- a/src/utils.js +++ b/src/utils.js @@ -16,6 +16,8 @@ import { import common from './diagrams/common/common'; import { configKeys } from './defaultConfig'; import { log } from './logger'; +import detectType from './diagram-api/detectType'; +import assignWithDepth from './assignWithDepth'; // Effectively an enum of the supported curve types, accessible by name const d3CurveTypes = { @@ -160,90 +162,6 @@ export const detectDirective = function (text, type = null) { } }; -/** - * @function detectType Detects the type of the graph text. Takes into consideration the possible - * existence of an %%init directive - * - * ```mermaid - * %%{initialize: {"startOnLoad": true, logLevel: "fatal" }}%% - * graph LR - * a-->b - * b-->c - * c-->d - * d-->e - * e-->f - * f-->g - * g-->h - * ``` - * @param {string} text The text defining the graph - * @param {{ - * class: { defaultRenderer: string } | undefined; - * state: { defaultRenderer: string } | undefined; - * flowchart: { defaultRenderer: string } | undefined; - * }} [cnf] - * @returns {string} A graph definition key - */ -export const detectType = function (text, cnf) { - text = text.replace(directive, '').replace(anyComment, '\n'); - if (text.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/)) { - return 'c4'; - } - - if (text.match(/^\s*sequenceDiagram/)) { - return 'sequence'; - } - - if (text.match(/^\s*gantt/)) { - return 'gantt'; - } - if (text.match(/^\s*classDiagram-v2/)) { - return 'classDiagram'; - } - if (text.match(/^\s*classDiagram/)) { - if (cnf && cnf.class && cnf.class.defaultRenderer === 'dagre-wrapper') return 'classDiagram'; - return 'class'; - } - - if (text.match(/^\s*stateDiagram-v2/)) { - return 'stateDiagram'; - } - - if (text.match(/^\s*stateDiagram/)) { - if (cnf && cnf.class && cnf.state.defaultRenderer === 'dagre-wrapper') return 'stateDiagram'; - return 'state'; - } - - if (text.match(/^\s*gitGraph/)) { - return 'gitGraph'; - } - if (text.match(/^\s*flowchart/)) { - return 'flowchart-v2'; - } - - if (text.match(/^\s*info/)) { - return 'info'; - } - if (text.match(/^\s*pie/)) { - return 'pie'; - } - - if (text.match(/^\s*erDiagram/)) { - return 'er'; - } - - if (text.match(/^\s*journey/)) { - return 'journey'; - } - - if (text.match(/^\s*requirement/) || text.match(/^\s*requirementDiagram/)) { - return 'requirement'; - } - if (cnf && cnf.flowchart && cnf.flowchart.defaultRenderer === 'dagre-wrapper') - return 'flowchart-v2'; - - return 'flowchart'; -}; - /** * Caches results of functions based on input * @@ -578,79 +496,6 @@ export const random = (options) => { return makeid(options.length); }; -/** - * @function assignWithDepth Extends the functionality of {@link ObjectConstructor.assign} with the - * ability to merge arbitrary-depth objects For each key in src with path `k` (recursively) - * performs an Object.assign(dst[`k`], src[`k`]) with a slight change from the typical handling of - * undefined for dst[`k`]: instead of raising an error, dst[`k`] is auto-initialized to {} and - * effectively merged with src[`k`]

Additionally, dissimilar types will not clobber unless the - * config.clobber parameter === true. Example: - * - * ```js - * let config_0 = { foo: { bar: 'bar' }, bar: 'foo' }; - * let config_1 = { foo: 'foo', bar: 'bar' }; - * let result = assignWithDepth(config_0, config_1); - * console.log(result); - * //-> result: { foo: { bar: 'bar' }, bar: 'bar' } - * ``` - * - * Traditional Object.assign would have clobbered foo in config_0 with foo in config_1. If src is a - * destructured array of objects and dst is not an array, assignWithDepth will apply each element - * of src to dst in order. - * @param dst - * @param src - * @param config - * @param dst - * @param src - * @param config - * @param dst - * @param src - * @param config - * @param {any} dst - The destination of the merge - * @param {any} src - The source object(s) to merge into destination - * @param {{ depth: number; clobber: boolean }} [config={ depth: 2, clobber: false }] - Depth: depth - * to traverse within src and dst for merging - clobber: should dissimilar types clobber (default: - * { depth: 2, clobber: false }). Default is `{ depth: 2, clobber: false }` - * @returns {any} - */ -export const assignWithDepth = function (dst, src, config) { - const { depth, clobber } = Object.assign({ depth: 2, clobber: false }, config); - if (Array.isArray(src) && !Array.isArray(dst)) { - src.forEach((s) => assignWithDepth(dst, s, config)); - return dst; - } else if (Array.isArray(src) && Array.isArray(dst)) { - src.forEach((s) => { - if (dst.indexOf(s) === -1) { - dst.push(s); - } - }); - return dst; - } - if (typeof dst === 'undefined' || depth <= 0) { - if (dst !== undefined && dst !== null && typeof dst === 'object' && typeof src === 'object') { - return Object.assign(dst, src); - } else { - return src; - } - } - if (typeof src !== 'undefined' && typeof dst === 'object' && typeof src === 'object') { - Object.keys(src).forEach((key) => { - if ( - typeof src[key] === 'object' && - (dst[key] === undefined || typeof dst[key] === 'object') - ) { - if (dst[key] === undefined) { - dst[key] = Array.isArray(src[key]) ? [] : {}; - } - dst[key] = assignWithDepth(dst[key], src[key], { depth: depth - 1, clobber }); - } else if (clobber || (typeof dst[key] !== 'object' && typeof src[key] !== 'object')) { - dst[key] = src[key]; - } - }); - } - return dst; -}; - export const getTextObj = function () { return { x: 0, @@ -1096,7 +941,6 @@ export default { setupGraphViewbox, detectInit, detectDirective, - detectType, isSubstringInArray, interpolateToCurve, calcLabelPosition, diff --git a/src/utils.spec.js b/src/utils.spec.js index b079beeeb19..31517c43aeb 100644 --- a/src/utils.spec.js +++ b/src/utils.spec.js @@ -1,52 +1,55 @@ import utils from './utils'; +import assignWithDepth from './assignWithDepth'; +import detectType from './diagram-api/detectType'; +import './diagram-api/diagram-orchestration'; describe('when assignWithDepth: should merge objects within objects', function () { it('should handle simple, depth:1 types (identity)', function () { let config_0 = { foo: 'bar', bar: 0 }; let config_1 = { foo: 'bar', bar: 0 }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual(config_1); }); it('should handle simple, depth:1 types (dst: undefined)', function () { let config_0 = undefined; let config_1 = { foo: 'bar', bar: 0 }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual(config_1); }); it('should handle simple, depth:1 types (src: undefined)', function () { let config_0 = { foo: 'bar', bar: 0 }; let config_1 = undefined; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual(config_0); }); it('should handle simple, depth:1 types (merge)', function () { let config_0 = { foo: 'bar', bar: 0 }; let config_1 = { foo: 'foo' }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual({ foo: 'foo', bar: 0 }); }); it('should handle depth:2 types (dst: orphan)', function () { let config_0 = { foo: 'bar', bar: { foo: 'bar' } }; let config_1 = { foo: 'bar' }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual(config_0); }); it('should handle depth:2 types (dst: object, src: simple type)', function () { let config_0 = { foo: 'bar', bar: { foo: 'bar' } }; let config_1 = { foo: 'foo', bar: 'should NOT clobber' }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar' } }); }); it('should handle depth:2 types (src: orphan)', function () { let config_0 = { foo: 'bar' }; let config_1 = { foo: 'bar', bar: { foo: 'bar' } }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual(config_1); }); it('should handle depth:2 types (merge)', function () { let config_0 = { foo: 'bar', bar: { foo: 'bar' }, boofar: 1 }; let config_1 = { foo: 'foo', bar: { bar: 0 }, foobar: 'foobar' }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual({ foo: 'foo', bar: { foo: 'bar', bar: 0 }, @@ -65,7 +68,7 @@ describe('when assignWithDepth: should merge objects within objects', function ( bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, foobar: 'foobar', }; - let result = utils.assignWithDepth(config_0, config_1); + let result = assignWithDepth(config_0, config_1); expect(result).toEqual({ foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'clobbered other foo' } } }, @@ -87,7 +90,7 @@ describe('when assignWithDepth: should merge objects within objects', function ( bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, foobar: 'foobar', }; - let result = utils.assignWithDepth(config_0, config_1, { depth: 1 }); + let result = assignWithDepth(config_0, config_1, { depth: 1 }); expect(result).toEqual({ foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, @@ -106,7 +109,7 @@ describe('when assignWithDepth: should merge objects within objects', function ( bar: { foo: 'foo', bar: { foo: { message: 'this' } } }, foobar: 'foobar', }; - let result = utils.assignWithDepth(config_0, config_1, { depth: 3 }); + let result = assignWithDepth(config_0, config_1, { depth: 3 }); expect(result).toEqual({ foo: 'foo', bar: { foo: 'foo', bar: { foo: { message: 'this', willbe: 'present' } } }, @@ -137,7 +140,7 @@ describe('when memoizing', function () { describe('when detecting chart type ', function () { it('should handle a graph definition', function () { const str = 'graph TB\nbfs1:queue'; - const type = utils.detectType(str); + const type = detectType(str); expect(type).toBe('flowchart'); }); it('should handle an initialize definition', function () { @@ -145,7 +148,7 @@ describe('when detecting chart type ', function () { %%{initialize: { 'logLevel': 0, 'theme': 'dark' }}%% sequenceDiagram Alice->Bob: hi`; - const type = utils.detectType(str); + const type = detectType(str); const init = utils.detectInit(str); expect(type).toBe('sequence'); expect(init).toEqual({ logLevel: 0, theme: 'dark' }); @@ -155,7 +158,7 @@ Alice->Bob: hi`; %%{init: { 'logLevel': 0, 'theme': 'dark' }}%% sequenceDiagram Alice->Bob: hi`; - const type = utils.detectType(str); + const type = detectType(str); const init = utils.detectInit(str); expect(type).toBe('sequence'); expect(init).toEqual({ logLevel: 0, theme: 'dark' }); @@ -165,7 +168,7 @@ Alice->Bob: hi`; %%{init: { 'logLevel': 0, 'theme': 'dark', 'config': {'wrap': true} } }%% sequenceDiagram Alice->Bob: hi`; - const type = utils.detectType(str); + const type = detectType(str); const init = utils.detectInit(str); expect(type).toBe('sequence'); expect(init).toEqual({ logLevel: 0, theme: 'dark', sequence: { wrap: true } }); @@ -180,7 +183,7 @@ Alice->Bob: hi`; }%% sequenceDiagram Alice->Bob: hi`; - const type = utils.detectType(str); + const type = detectType(str); const init = utils.detectInit(str); expect(type).toBe('sequence'); expect(init).toEqual({ logLevel: 0, theme: 'dark' }); @@ -195,25 +198,25 @@ Alice->Bob: hi`; }%% sequenceDiagram Alice->Bob: hi`; - const type = utils.detectType(str); + const type = detectType(str); const init = utils.detectInit(str); expect(type).toBe('sequence'); expect(init).toEqual({ logLevel: 0, theme: 'dark' }); }); it('should handle a graph definition with leading spaces', function () { const str = ' graph TB\nbfs1:queue'; - const type = utils.detectType(str); + const type = detectType(str); expect(type).toBe('flowchart'); }); it('should handle a graph definition with leading spaces and newline', function () { const str = ' \n graph TB\nbfs1:queue'; - const type = utils.detectType(str); + const type = detectType(str); expect(type).toBe('flowchart'); }); it('should handle a graph definition for gitGraph', function () { const str = ' \n gitGraph TB:\nbfs1:queue'; - const type = utils.detectType(str); + const type = detectType(str); expect(type).toBe('gitGraph'); }); }); diff --git a/test.js b/test.js new file mode 100644 index 00000000000..824cfec8884 --- /dev/null +++ b/test.js @@ -0,0 +1,5 @@ +function apa() { + // comment's + const a = 1; + return 'apa' + a; +} From dee9cfea85f6fb57577efcf0a5cbd407e28866bb Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Wed, 20 Jul 2022 11:32:21 +0200 Subject: [PATCH 04/13] Reverting to cypress 9.7 in order to get applitools back in the game --- .../other/configuration.spec.js | 0 .../{e2e => integration}/other/ghsa.spec.js | 0 .../other/interaction.spec.js | 0 .../other/rerender.spec.js | 0 .../other/webpackUsage.spec.js | 0 .../{e2e => integration}/other/xss.spec.js | 0 .../rendering/appli.spec.js | 0 .../rendering/classDiagram-v2.spec.js | 0 .../rendering/classDiagram.spec.js | 0 .../rendering/conf-and-directives.spec.js | 0 .../rendering/current.spec.js | 0 .../rendering/debug.spec.js | 0 .../rendering/erDiagram.spec.js | 0 .../rendering/flowchart-v2.spec.js | 0 .../rendering/flowchart.spec.js | 0 .../rendering/gantt.spec.js | 0 .../rendering/gitGraph.spec.js | 0 .../rendering/info.spec.js | 0 .../rendering/journey.spec.js | 0 .../rendering/pie.spec.js | 0 .../rendering/requirement.spec.js | 0 .../rendering/sequencediagram.spec.js | 0 .../rendering/stateDiagram-v2.spec.js | 0 .../rendering/stateDiagram.spec.js | 0 .../rendering/theme.spec.js | 0 cypress/platform/knsv.html | 17 +++++++--- cypress/plugins/index.js | 32 +++++++++++++++++++ package.json | 6 ++-- yarn.lock | 24 +++++++------- 29 files changed, 59 insertions(+), 20 deletions(-) rename cypress/{e2e => integration}/other/configuration.spec.js (100%) rename cypress/{e2e => integration}/other/ghsa.spec.js (100%) rename cypress/{e2e => integration}/other/interaction.spec.js (100%) rename cypress/{e2e => integration}/other/rerender.spec.js (100%) rename cypress/{e2e => integration}/other/webpackUsage.spec.js (100%) rename cypress/{e2e => integration}/other/xss.spec.js (100%) rename cypress/{e2e => integration}/rendering/appli.spec.js (100%) rename cypress/{e2e => integration}/rendering/classDiagram-v2.spec.js (100%) rename cypress/{e2e => integration}/rendering/classDiagram.spec.js (100%) rename cypress/{e2e => integration}/rendering/conf-and-directives.spec.js (100%) rename cypress/{e2e => integration}/rendering/current.spec.js (100%) rename cypress/{e2e => integration}/rendering/debug.spec.js (100%) rename cypress/{e2e => integration}/rendering/erDiagram.spec.js (100%) rename cypress/{e2e => integration}/rendering/flowchart-v2.spec.js (100%) rename cypress/{e2e => integration}/rendering/flowchart.spec.js (100%) rename cypress/{e2e => integration}/rendering/gantt.spec.js (100%) rename cypress/{e2e => integration}/rendering/gitGraph.spec.js (100%) rename cypress/{e2e => integration}/rendering/info.spec.js (100%) rename cypress/{e2e => integration}/rendering/journey.spec.js (100%) rename cypress/{e2e => integration}/rendering/pie.spec.js (100%) rename cypress/{e2e => integration}/rendering/requirement.spec.js (100%) rename cypress/{e2e => integration}/rendering/sequencediagram.spec.js (100%) rename cypress/{e2e => integration}/rendering/stateDiagram-v2.spec.js (100%) rename cypress/{e2e => integration}/rendering/stateDiagram.spec.js (100%) rename cypress/{e2e => integration}/rendering/theme.spec.js (100%) create mode 100644 cypress/plugins/index.js diff --git a/cypress/e2e/other/configuration.spec.js b/cypress/integration/other/configuration.spec.js similarity index 100% rename from cypress/e2e/other/configuration.spec.js rename to cypress/integration/other/configuration.spec.js diff --git a/cypress/e2e/other/ghsa.spec.js b/cypress/integration/other/ghsa.spec.js similarity index 100% rename from cypress/e2e/other/ghsa.spec.js rename to cypress/integration/other/ghsa.spec.js diff --git a/cypress/e2e/other/interaction.spec.js b/cypress/integration/other/interaction.spec.js similarity index 100% rename from cypress/e2e/other/interaction.spec.js rename to cypress/integration/other/interaction.spec.js diff --git a/cypress/e2e/other/rerender.spec.js b/cypress/integration/other/rerender.spec.js similarity index 100% rename from cypress/e2e/other/rerender.spec.js rename to cypress/integration/other/rerender.spec.js diff --git a/cypress/e2e/other/webpackUsage.spec.js b/cypress/integration/other/webpackUsage.spec.js similarity index 100% rename from cypress/e2e/other/webpackUsage.spec.js rename to cypress/integration/other/webpackUsage.spec.js diff --git a/cypress/e2e/other/xss.spec.js b/cypress/integration/other/xss.spec.js similarity index 100% rename from cypress/e2e/other/xss.spec.js rename to cypress/integration/other/xss.spec.js diff --git a/cypress/e2e/rendering/appli.spec.js b/cypress/integration/rendering/appli.spec.js similarity index 100% rename from cypress/e2e/rendering/appli.spec.js rename to cypress/integration/rendering/appli.spec.js diff --git a/cypress/e2e/rendering/classDiagram-v2.spec.js b/cypress/integration/rendering/classDiagram-v2.spec.js similarity index 100% rename from cypress/e2e/rendering/classDiagram-v2.spec.js rename to cypress/integration/rendering/classDiagram-v2.spec.js diff --git a/cypress/e2e/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js similarity index 100% rename from cypress/e2e/rendering/classDiagram.spec.js rename to cypress/integration/rendering/classDiagram.spec.js diff --git a/cypress/e2e/rendering/conf-and-directives.spec.js b/cypress/integration/rendering/conf-and-directives.spec.js similarity index 100% rename from cypress/e2e/rendering/conf-and-directives.spec.js rename to cypress/integration/rendering/conf-and-directives.spec.js diff --git a/cypress/e2e/rendering/current.spec.js b/cypress/integration/rendering/current.spec.js similarity index 100% rename from cypress/e2e/rendering/current.spec.js rename to cypress/integration/rendering/current.spec.js diff --git a/cypress/e2e/rendering/debug.spec.js b/cypress/integration/rendering/debug.spec.js similarity index 100% rename from cypress/e2e/rendering/debug.spec.js rename to cypress/integration/rendering/debug.spec.js diff --git a/cypress/e2e/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js similarity index 100% rename from cypress/e2e/rendering/erDiagram.spec.js rename to cypress/integration/rendering/erDiagram.spec.js diff --git a/cypress/e2e/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js similarity index 100% rename from cypress/e2e/rendering/flowchart-v2.spec.js rename to cypress/integration/rendering/flowchart-v2.spec.js diff --git a/cypress/e2e/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js similarity index 100% rename from cypress/e2e/rendering/flowchart.spec.js rename to cypress/integration/rendering/flowchart.spec.js diff --git a/cypress/e2e/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js similarity index 100% rename from cypress/e2e/rendering/gantt.spec.js rename to cypress/integration/rendering/gantt.spec.js diff --git a/cypress/e2e/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js similarity index 100% rename from cypress/e2e/rendering/gitGraph.spec.js rename to cypress/integration/rendering/gitGraph.spec.js diff --git a/cypress/e2e/rendering/info.spec.js b/cypress/integration/rendering/info.spec.js similarity index 100% rename from cypress/e2e/rendering/info.spec.js rename to cypress/integration/rendering/info.spec.js diff --git a/cypress/e2e/rendering/journey.spec.js b/cypress/integration/rendering/journey.spec.js similarity index 100% rename from cypress/e2e/rendering/journey.spec.js rename to cypress/integration/rendering/journey.spec.js diff --git a/cypress/e2e/rendering/pie.spec.js b/cypress/integration/rendering/pie.spec.js similarity index 100% rename from cypress/e2e/rendering/pie.spec.js rename to cypress/integration/rendering/pie.spec.js diff --git a/cypress/e2e/rendering/requirement.spec.js b/cypress/integration/rendering/requirement.spec.js similarity index 100% rename from cypress/e2e/rendering/requirement.spec.js rename to cypress/integration/rendering/requirement.spec.js diff --git a/cypress/e2e/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js similarity index 100% rename from cypress/e2e/rendering/sequencediagram.spec.js rename to cypress/integration/rendering/sequencediagram.spec.js diff --git a/cypress/e2e/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js similarity index 100% rename from cypress/e2e/rendering/stateDiagram-v2.spec.js rename to cypress/integration/rendering/stateDiagram-v2.spec.js diff --git a/cypress/e2e/rendering/stateDiagram.spec.js b/cypress/integration/rendering/stateDiagram.spec.js similarity index 100% rename from cypress/e2e/rendering/stateDiagram.spec.js rename to cypress/integration/rendering/stateDiagram.spec.js diff --git a/cypress/e2e/rendering/theme.spec.js b/cypress/integration/rendering/theme.spec.js similarity index 100% rename from cypress/e2e/rendering/theme.spec.js rename to cypress/integration/rendering/theme.spec.js diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index 8bc9f88e22e..c8109ba17cd 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -218,11 +218,18 @@ }

- stateDiagram - accTitle: Apa - accDescr: One that can climb better then any man - [*] --> S1 - state "Some long name" as S1 +graph LR + A[[subroutine shape test]] + A -->|Get money| B[[Go shopping]] + B --> C[[Let me think...
Do I want something for work,
something to spend every free second with,
or something to get around?]] + C -->|One| D[[Laptop]] + C -->|Two| E[[iPhone]] + C -->|Three| F[[Car
wroom wroom]] + click A "index.html#link-clicked" "link test" + click B testClick "click test" + classDef someclass fill:#f96; + class A someclass; + class C someclass;
classDiagram diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 00000000000..2c98a54ade0 --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,32 @@ +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +// module.exports = (on, config) => { +// // `on` is used to hook into various events Cypress emits +// // `config` is the resolved Cypress config +// } + +const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin'); +require('@applitools/eyes-cypress')(module); + +module.exports = (on, config) => { + addMatchImageSnapshotPlugin(on, config); + // copy any needed variables from process.env to config.env + config.env.useAppli = process.env.USE_APPLI ? true : false; + config.env.codeBranch = process.env.APPLI_BRANCH; + + // do not forget to return the changed config object! + return config; +}; + +require('@applitools/eyes-cypress')(module); diff --git a/package.json b/package.json index d295b5f5556..b49cb0ee22b 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "postbuild": "documentation build src/mermaidAPI.js src/config.js src/defaultConfig.js --shallow -f md --markdown-toc false > docs/Setup.md", "build:watch": "yarn build:development --watch", "release": "yarn build", - "lint": "eslint ./ --ext .js,.json,.html,.md", + "lint": "eslint ./ --ext .js,.json,.html", "lint:fix": "yarn lint --fix", "e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js", "cypress": "cypress run", @@ -81,7 +81,7 @@ "concurrently": "^7.0.0", "coveralls": "^3.0.2", "css-to-string-loader": "^0.1.3", - "cypress": "10.3.0", + "cypress": "9.7.0", "cypress-image-snapshot": "^4.0.1", "documentation": "13.2.0", "eslint": "^8.4.1", @@ -112,7 +112,7 @@ "webpack-merge": "^5.8.0", "webpack-node-externals": "^3.0.0" }, - "resolutions": { + "resolutions": { "d3": "^7.0.0" }, "files": [ diff --git a/yarn.lock b/yarn.lock index 15beabbe665..853d09418e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -70,12 +70,12 @@ "@applitools/utils" "1.3.10" "@applitools/eyes-cypress@^3.25.7": - version "3.26.4" - resolved "https://registry.yarnpkg.com/@applitools/eyes-cypress/-/eyes-cypress-3.26.4.tgz#e1a511cc6ff9f851e29d918cebf9008922e6650d" - integrity sha512-YTlLlNBEwyLKzkKH9kAWz17GkDpI5kkuFIP+Gm4BGjRYawpLpF9GvxlCng0Q+Lli1jMIEIP6tZnjrapHbKqm4A== + version "3.26.6" + resolved "https://registry.yarnpkg.com/@applitools/eyes-cypress/-/eyes-cypress-3.26.6.tgz#a629ef45e1ae37b2234a79fac197f858eae96ccf" + integrity sha512-bj6goVPMdptgRreFcdoOKWJzkebp3R0TYj7G8OGDm6H2cHPQGLwPT+1Z+1Moj9XGy1X6Pgur6TeTtGE4q/QsUw== dependencies: "@applitools/eyes-api" "1.7.4" - "@applitools/eyes-universal" "2.9.6" + "@applitools/eyes-universal" "2.9.7" "@applitools/functional-commons" "1.6.0" "@applitools/logger" "1.1.15" "@applitools/visual-grid-client" "15.13.6" @@ -102,10 +102,10 @@ chalk "3.0.0" tunnel "0.0.6" -"@applitools/eyes-universal@2.9.6": - version "2.9.6" - resolved "https://registry.yarnpkg.com/@applitools/eyes-universal/-/eyes-universal-2.9.6.tgz#65dad010283d5117704137e6c10e4592c6bdd7e1" - integrity sha512-Un6/p8CCI7bdootTDnjpls/mo53Q/3YV8VQQalbkR7Xex63Y4/r4Y/xowoAZb+Q/Iq/BblMwhKFh11dEePFMpA== +"@applitools/eyes-universal@2.9.7": + version "2.9.7" + resolved "https://registry.yarnpkg.com/@applitools/eyes-universal/-/eyes-universal-2.9.7.tgz#0e4e5309e04abbeeb2f29a9e5d63a2feb90de55f" + integrity sha512-pqmgAt2MSSYsT1Iye0motD6x4O9IMF0CCpqKbllU2Om6KSSedT8+c8V0nr+SSrWxKYnvZ6Et1MPs2xYibOywsg== dependencies: "@applitools/execution-grid-client" "1.1.22" "@applitools/eyes-sdk-core" "13.8.12" @@ -4220,10 +4220,10 @@ cypress-image-snapshot@^4.0.1: pkg-dir "^3.0.0" term-img "^4.0.0" -cypress@10.3.0: - version "10.3.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.3.0.tgz#fae8d32f0822fcfb938e79c7c31ef344794336ae" - integrity sha512-txkQWKzvBVnWdCuKs5Xc08gjpO89W2Dom2wpZgT9zWZT5jXxqPIxqP/NC1YArtkpmp3fN5HW8aDjYBizHLUFvg== +cypress@9.7.0: + version "9.7.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.7.0.tgz#bf55b2afd481f7a113ef5604aa8b693564b5e744" + integrity sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" From 5a6d8aee656ac0ab6691e9cfbad638410685e895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Jul 2022 09:38:39 +0000 Subject: [PATCH 05/13] chore(deps-dev): bump jest from 28.1.2 to 28.1.3 Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 28.1.2 to 28.1.3. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v28.1.3/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- yarn.lock | 646 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 400 insertions(+), 246 deletions(-) diff --git a/yarn.lock b/yarn.lock index 853d09418e3..43bcc457607 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1750,49 +1750,49 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.1.tgz#305f8ca50b6e70413839f54c0e002b60a0f2fd7d" - integrity sha512-0RiUocPVFEm3WRMOStIHbRWllG6iW6E3/gUPnf4lkrVFyXIIDeCe+vlKeYyFOMhB2EPE6FLFCNADSOOQMaqvyA== +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== dependencies: - "@jest/types" "^28.1.1" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^28.1.1" - jest-util "^28.1.1" + jest-message-util "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" -"@jest/core@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.2.tgz#eac519b9acbd154313854b8823a47b5c645f785a" - integrity sha512-Xo4E+Sb/nZODMGOPt2G3cMmCBqL4/W2Ijwr7/mrXlq4jdJwcFQ/9KrrJZT2adQRk2otVBXXOz1GRQ4Z5iOgvRQ== +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== dependencies: - "@jest/console" "^28.1.1" - "@jest/reporters" "^28.1.2" - "@jest/test-result" "^28.1.1" - "@jest/transform" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^28.0.2" - jest-config "^28.1.2" - jest-haste-map "^28.1.1" - jest-message-util "^28.1.1" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" jest-regex-util "^28.0.2" - jest-resolve "^28.1.1" - jest-resolve-dependencies "^28.1.2" - jest-runner "^28.1.2" - jest-runtime "^28.1.2" - jest-snapshot "^28.1.2" - jest-util "^28.1.1" - jest-validate "^28.1.1" - jest-watcher "^28.1.1" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" micromatch "^4.0.4" - pretty-format "^28.1.1" + pretty-format "^28.1.3" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" @@ -1807,20 +1807,30 @@ "@types/node" "*" jest-mock "^28.1.1" -"@jest/expect-utils@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.1.tgz#d84c346025b9f6f3886d02c48a6177e2b0360587" - integrity sha512-n/ghlvdhCdMI/hTcnn4qV57kQuV9OTsZzH1TTCVARANKhl6hXJqLKUkwX69ftMGpsbpt96SsDD8n8LD2d9+FRw== +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== + dependencies: + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== dependencies: jest-get-type "^28.0.2" -"@jest/expect@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.2.tgz#0b25acedff46e1e1e5606285306c8a399c12534f" - integrity sha512-HBzyZBeFBiOelNbBKN0pilWbbrGvwDUwAqMC46NVJmWm8AVkuE58NbG1s7DR4cxFt4U5cVLxofAoHxgvC5MyOw== +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== dependencies: - expect "^28.1.1" - jest-snapshot "^28.1.2" + expect "^28.1.3" + jest-snapshot "^28.1.3" "@jest/fake-timers@^28.1.2": version "28.1.2" @@ -1834,25 +1844,37 @@ jest-mock "^28.1.1" jest-util "^28.1.1" -"@jest/globals@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.2.tgz#92fab296e337c7309c25e4202fb724f62249d83f" - integrity sha512-cz0lkJVDOtDaYhvT3Fv2U1B6FtBnV+OpEyJCzTHM1fdoTsU4QNLAt/H4RkiwEUU+dL4g/MFsoTuHeT2pvbo4Hg== +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== dependencies: - "@jest/environment" "^28.1.2" - "@jest/expect" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" -"@jest/reporters@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.2.tgz#0327be4ce4d0d9ae49e7908656f89669d0c2a260" - integrity sha512-/whGLhiwAqeCTmQEouSigUZJPVl7sW8V26EiboImL+UyXznnr1a03/YZ2BX8OlFw0n+Zlwu+EZAITZtaeRTxyA== +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" + +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.1.1" - "@jest/test-result" "^28.1.1" - "@jest/transform" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@jridgewell/trace-mapping" "^0.3.13" "@types/node" "*" chalk "^4.0.0" @@ -1865,9 +1887,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^28.1.1" - jest-util "^28.1.1" - jest-worker "^28.1.1" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" @@ -1881,6 +1903,13 @@ dependencies: "@sinclair/typebox" "^0.23.3" +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + "@jest/source-map@^28.1.2": version "28.1.2" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" @@ -1890,24 +1919,24 @@ callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.1.tgz#c6f18d1bbb01aa88925dd687872a75f8414b317a" - integrity sha512-hPmkugBktqL6rRzwWAtp1JtYT4VHwv8OQ+9lE5Gymj6dHzubI/oJHMUpPOt8NrdVWSrz9S7bHjJUmv2ggFoUNQ== +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== dependencies: - "@jest/console" "^28.1.1" - "@jest/types" "^28.1.1" + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.1.tgz#f594ee2331df75000afe0d1ae3237630ecec732e" - integrity sha512-nuL+dNSVMcWB7OOtgb0EGH5AjO4UBCt68SLP08rwmC+iRhyuJWS9MtZ/MpipxFwKAlHFftbMsydXqWre8B0+XA== +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== dependencies: - "@jest/test-result" "^28.1.1" + "@jest/test-result" "^28.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.1.1" + jest-haste-map "^28.1.3" slash "^3.0.0" "@jest/transform@^28.1.2": @@ -1931,12 +1960,33 @@ slash "^3.0.0" write-file-atomic "^4.0.1" -"@jest/types@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.1.tgz#d059bbc80e6da6eda9f081f293299348bd78ee0b" - integrity sha512-vRXVqSg1VhDnB8bWcmvLzmg0Bt9CRKVgHPXqYwvWMX3TvAjeO+nRuK6+VdTKCtWOvYlmkF/HqNAL/z+N3B53Kw== +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== dependencies: - "@jest/schemas" "^28.0.2" + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + +"@jest/types@^28.1.1", "@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -2031,6 +2081,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== +"@sinclair/typebox@^0.24.1": + version "0.24.20" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.20.tgz#11a657875de6008622d53f56e063a6347c51a6dd" + integrity sha512-kVaO5aEFZb33nPMTZBxiPEkY+slxiPtqC7QX8f9B3eGOMBvEfuMfxp9DSTTCsRJPumPKjrge4yagyssO4q6qzQ== + "@sindresorhus/is@^4.0.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" @@ -3050,7 +3105,7 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" -babel-jest@^28.0.3, babel-jest@^28.1.2: +babel-jest@^28.0.3: version "28.1.2" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.2.tgz#2b37fb81439f14d34d8b2cc4a4bd7efabf9acbfe" integrity sha512-pfmoo6sh4L/+5/G2OOfQrGJgvH7fTa1oChnuYH2G/6gA+JwDvO8PELwvwnofKBMNrQsam0Wy/Rw+QSrBNewq2Q== @@ -3063,6 +3118,19 @@ babel-jest@^28.0.3, babel-jest@^28.1.2: graceful-fs "^4.2.9" slash "^3.0.0" +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== + dependencies: + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-loader@^8.2.2: version "8.2.5" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" @@ -3101,6 +3169,16 @@ babel-plugin-jest-hoist@^28.1.1: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-plugin-polyfill-corejs2@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" @@ -3151,6 +3229,14 @@ babel-preset-jest@^28.1.1: babel-plugin-jest-hoist "^28.1.1" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== + dependencies: + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" + babelify@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/babelify/-/babelify-10.0.0.tgz#fe73b1a22583f06680d8d072e25a1e0d1d1d7fb5" @@ -5472,16 +5558,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.1.tgz#ca6fff65f6517cf7220c2e805a49c19aea30b420" - integrity sha512-/AANEwGL0tWBwzLNOvO0yUdy2D52jVdNXppOqswC49sxMN2cPWsGCQdzuIf9tj6hHoBQzNvx75JUYuQAckPo3w== +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== dependencies: - "@jest/expect-utils" "^28.1.1" + "@jest/expect-utils" "^28.1.3" jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.1" - jest-message-util "^28.1.1" - jest-util "^28.1.1" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" express@^4.17.3: version "4.17.3" @@ -7046,94 +7132,94 @@ iterm2-version@^4.1.0: app-path "^3.2.0" plist "^3.0.1" -jest-changed-files@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.0.2.tgz#7d7810660a5bd043af9e9cfbe4d58adb05e91531" - integrity sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA== +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== dependencies: execa "^5.0.0" - throat "^6.0.1" + p-limit "^3.1.0" -jest-circus@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.2.tgz#0d5a5623eccb244efe87d1edc365696e4fcf80ce" - integrity sha512-E2vdPIJG5/69EMpslFhaA46WkcrN74LI5V/cSJ59L7uS8UNoXbzTxmwhpi9XrIL3zqvMt5T0pl5k2l2u2GwBNQ== +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== dependencies: - "@jest/environment" "^28.1.2" - "@jest/expect" "^28.1.2" - "@jest/test-result" "^28.1.1" - "@jest/types" "^28.1.1" + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^28.1.1" - jest-matcher-utils "^28.1.1" - jest-message-util "^28.1.1" - jest-runtime "^28.1.2" - jest-snapshot "^28.1.2" - jest-util "^28.1.1" - pretty-format "^28.1.1" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" slash "^3.0.0" stack-utils "^2.0.3" - throat "^6.0.1" -jest-cli@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.2.tgz#b89012e5bad14135e71b1628b85475d3773a1bbc" - integrity sha512-l6eoi5Do/IJUXAFL9qRmDiFpBeEJAnjJb1dcd9i/VWfVWbp3mJhuH50dNtX67Ali4Ecvt4eBkWb4hXhPHkAZTw== +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== dependencies: - "@jest/core" "^28.1.2" - "@jest/test-result" "^28.1.1" - "@jest/types" "^28.1.1" + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^28.1.2" - jest-util "^28.1.1" - jest-validate "^28.1.1" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.2.tgz#ba00ad30caf62286c86e7c1099e915218a0ac8c6" - integrity sha512-g6EfeRqddVbjPVBVY4JWpUY4IvQoFRIZcv4V36QkqzE0IGhEC/VkugFeBMAeUE7PRgC8KJF0yvJNDeQRbamEVA== +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.1.1" - "@jest/types" "^28.1.1" - babel-jest "^28.1.2" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^28.1.2" - jest-environment-node "^28.1.2" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" jest-get-type "^28.0.2" jest-regex-util "^28.0.2" - jest-resolve "^28.1.1" - jest-runner "^28.1.2" - jest-util "^28.1.1" - jest-validate "^28.1.1" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^28.1.1" + pretty-format "^28.1.3" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.1.tgz#1a3eedfd81ae79810931c63a1d0f201b9120106c" - integrity sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg== +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== dependencies: chalk "^4.0.0" diff-sequences "^28.1.1" jest-get-type "^28.0.2" - pretty-format "^28.1.1" + pretty-format "^28.1.3" jest-docblock@^28.1.1: version "28.1.1" @@ -7142,16 +7228,16 @@ jest-docblock@^28.1.1: dependencies: detect-newline "^3.0.0" -jest-each@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.1.tgz#ba5238dacf4f31d9fe23ddc2c44c01e7c23885c4" - integrity sha512-A042rqh17ZvEhRceDMi784ppoXR7MWGDEKTXEZXb4svt0eShMZvijGxzKsx+yIjeE8QYmHPrnHiTSQVhN4nqaw== +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== dependencies: - "@jest/types" "^28.1.1" + "@jest/types" "^28.1.3" chalk "^4.0.0" jest-get-type "^28.0.2" - jest-util "^28.1.1" - pretty-format "^28.1.1" + jest-util "^28.1.3" + pretty-format "^28.1.3" jest-environment-jsdom@^28.0.2: version "28.1.2" @@ -7167,17 +7253,17 @@ jest-environment-jsdom@^28.0.2: jest-util "^28.1.1" jsdom "^19.0.0" -jest-environment-node@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.2.tgz#3e2eb47f6d173b0648d5f7c717cb1c26651d5c8a" - integrity sha512-oYsZz9Qw27XKmOgTtnl0jW7VplJkN2oeof+SwAwKFQacq3CLlG9u4kTGuuLWfvu3J7bVutWlrbEQMOCL/jughw== +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== dependencies: - "@jest/environment" "^28.1.2" - "@jest/fake-timers" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - jest-mock "^28.1.1" - jest-util "^28.1.1" + jest-mock "^28.1.3" + jest-util "^28.1.3" jest-get-type@^28.0.2: version "28.0.2" @@ -7203,6 +7289,25 @@ jest-haste-map@^28.1.1: optionalDependencies: fsevents "^2.3.2" +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + jest-image-snapshot@4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/jest-image-snapshot/-/jest-image-snapshot-4.2.0.tgz#559d7ade69e9918517269cef184261c80029a69e" @@ -7218,23 +7323,23 @@ jest-image-snapshot@4.2.0: rimraf "^2.6.2" ssim.js "^3.1.1" -jest-leak-detector@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.1.tgz#537f37afd610a4b3f4cab15e06baf60484548efb" - integrity sha512-4jvs8V8kLbAaotE+wFR7vfUGf603cwYtFf1/PYEsyX2BAjSzj8hQSVTP6OWzseTl0xL6dyHuKs2JAks7Pfubmw== +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== dependencies: jest-get-type "^28.0.2" - pretty-format "^28.1.1" + pretty-format "^28.1.3" -jest-matcher-utils@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.1.tgz#a7c4653c2b782ec96796eb3088060720f1e29304" - integrity sha512-NPJPRWrbmR2nAJ+1nmnfcKKzSwgfaciCCrYZzVnNoxVoyusYWIjkBMNvu0RHJe7dNj4hH3uZOPZsQA+xAYWqsw== +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== dependencies: chalk "^4.0.0" - jest-diff "^28.1.1" + jest-diff "^28.1.3" jest-get-type "^28.0.2" - pretty-format "^28.1.1" + pretty-format "^28.1.3" jest-message-util@^28.1.1: version "28.1.1" @@ -7251,6 +7356,21 @@ jest-message-util@^28.1.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^28.1.1: version "28.1.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.1.tgz#37903d269427fa1ef5b2447be874e1c62a39a371" @@ -7259,6 +7379,14 @@ jest-mock@^28.1.1: "@jest/types" "^28.1.1" "@types/node" "*" +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" @@ -7269,111 +7397,111 @@ jest-regex-util@^28.0.2: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== -jest-resolve-dependencies@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.2.tgz#ca528858e0c6642d5a1dda8fc7cda10230c275bc" - integrity sha512-OXw4vbOZuyRTBi3tapWBqdyodU+T33ww5cPZORuTWkg+Y8lmsxQlVu3MWtJh6NMlKRTHQetF96yGPv01Ye7Mbg== +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== dependencies: jest-regex-util "^28.0.2" - jest-snapshot "^28.1.2" + jest-snapshot "^28.1.3" -jest-resolve@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.1.tgz#bc2eaf384abdcc1aaf3ba7c50d1adf01e59095e5" - integrity sha512-/d1UbyUkf9nvsgdBildLe6LAD4DalgkgZcKd0nZ8XUGPyA/7fsnaQIlKVnDiuUXv/IeZhPEDrRJubVSulxrShA== +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.1" + jest-haste-map "^28.1.3" jest-pnp-resolver "^1.2.2" - jest-util "^28.1.1" - jest-validate "^28.1.1" + jest-util "^28.1.3" + jest-validate "^28.1.3" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.2.tgz#f293409592a62234285a71237e38499a3554e350" - integrity sha512-6/k3DlAsAEr5VcptCMdhtRhOoYClZQmxnVMZvZ/quvPGRpN7OBQYPIC32tWSgOnbgqLXNs5RAniC+nkdFZpD4A== +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== dependencies: - "@jest/console" "^28.1.1" - "@jest/environment" "^28.1.2" - "@jest/test-result" "^28.1.1" - "@jest/transform" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.10.2" graceful-fs "^4.2.9" jest-docblock "^28.1.1" - jest-environment-node "^28.1.2" - jest-haste-map "^28.1.1" - jest-leak-detector "^28.1.1" - jest-message-util "^28.1.1" - jest-resolve "^28.1.1" - jest-runtime "^28.1.2" - jest-util "^28.1.1" - jest-watcher "^28.1.1" - jest-worker "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" source-map-support "0.5.13" - throat "^6.0.1" -jest-runtime@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.2.tgz#d68f34f814a848555a345ceda23289f14d59a688" - integrity sha512-i4w93OsWzLOeMXSi9epmakb2+3z0AchZtUQVF1hesBmcQQy4vtaql5YdVe9KexdJaVRyPDw8DoBR0j3lYsZVYw== +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== dependencies: - "@jest/environment" "^28.1.2" - "@jest/fake-timers" "^28.1.2" - "@jest/globals" "^28.1.2" + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" "@jest/source-map" "^28.1.2" - "@jest/test-result" "^28.1.1" - "@jest/transform" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" execa "^5.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.1.1" - jest-message-util "^28.1.1" - jest-mock "^28.1.1" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" jest-regex-util "^28.0.2" - jest-resolve "^28.1.1" - jest-snapshot "^28.1.2" - jest-util "^28.1.1" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^28.1.2: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.2.tgz#93d31b87b11b384f5946fe0767541496135f8d52" - integrity sha512-wzrieFttZYfLvrCVRJxX+jwML2YTArOUqFpCoSVy1QUapx+LlV9uLbV/mMEhYj4t7aMeE9aSQFHSvV/oNoDAMA== +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.1.1" - "@jest/transform" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^28.1.1" + expect "^28.1.3" graceful-fs "^4.2.9" - jest-diff "^28.1.1" + jest-diff "^28.1.3" jest-get-type "^28.0.2" - jest-haste-map "^28.1.1" - jest-matcher-utils "^28.1.1" - jest-message-util "^28.1.1" - jest-util "^28.1.1" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" natural-compare "^1.4.0" - pretty-format "^28.1.1" + pretty-format "^28.1.3" semver "^7.3.5" jest-util@^28.1.1: @@ -7388,30 +7516,42 @@ jest-util@^28.1.1: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.1.tgz#59b7b339b3c85b5144bd0c06ad3600f503a4acc8" - integrity sha512-Kpf6gcClqFCIZ4ti5++XemYJWUPCFUW+N2gknn+KgnDf549iLul3cBuKVe1YcWRlaF8tZV8eJCap0eECOEE3Ug== +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== dependencies: - "@jest/types" "^28.1.1" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== + dependencies: + "@jest/types" "^28.1.3" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^28.0.2" leven "^3.1.0" - pretty-format "^28.1.1" + pretty-format "^28.1.3" -jest-watcher@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.1.tgz#533597fb3bfefd52b5cd115cd916cffd237fb60c" - integrity sha512-RQIpeZ8EIJMxbQrXpJQYIIlubBnB9imEHsxxE41f54ZwcqWLysL/A0ZcdMirf+XsMn3xfphVQVV4EW0/p7i7Ug== +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== dependencies: - "@jest/test-result" "^28.1.1" - "@jest/types" "^28.1.1" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.10.2" - jest-util "^28.1.1" + jest-util "^28.1.3" string-length "^4.0.1" jest-worker@^27.4.5: @@ -7432,15 +7572,24 @@ jest-worker@^28.1.1: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@^28.0.3: - version "28.1.2" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.2.tgz#451ff24081ce31ca00b07b60c61add13aa96f8eb" - integrity sha512-Tuf05DwLeCh2cfWCQbcz9UxldoDyiR1E9Igaei5khjonKncYdc6LDfynKCEWozK0oLE3GD+xKAo2u8x/0s6GOg== + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== dependencies: - "@jest/core" "^28.1.2" - "@jest/types" "^28.1.1" + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" import-local "^3.0.2" - jest-cli "^28.1.2" + jest-cli "^28.1.3" jison-lex@0.3.x: version "0.3.4" @@ -8903,7 +9052,7 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -9316,6 +9465,16 @@ pretty-format@^28.1.1: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -10859,11 +11018,6 @@ throat@5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" From 8681e78e50ca48462cfe8677551455ea1e397d41 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Wed, 20 Jul 2022 14:39:01 +0200 Subject: [PATCH 06/13] Fixes for rendering tests --- cypress/fixtures/example.json | 5 ++ cypress/helpers/util.js | 3 +- .../rendering/sequencediagram.spec.js | 2 +- cypress/platform/knsv.html | 51 ++++++++++++++----- docs/Setup.md | 41 +++++++-------- src/diagram-api/diagram-orchestration.js | 21 ++++---- src/diagram-api/diagramAPI.js | 2 +- src/diagrams/sequence/sequenceDb.js | 2 +- src/diagrams/sequence/svgDraw.js | 5 +- src/mermaidAPI.js | 3 +- 10 files changed, 81 insertions(+), 54 deletions(-) create mode 100644 cypress/fixtures/example.json diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 00000000000..02e4254378e --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js index dd3fdd2c924..0a52a335b22 100644 --- a/cypress/helpers/util.js +++ b/cypress/helpers/util.js @@ -42,7 +42,8 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) => if (!options.fontSize) { options.fontSize = '16px'; } - const useAppli = Cypress.env('useAppli'); + // const useAppli = Cypress.env('useAppli'); + const useAppli = false; const branch = Cypress.env('codeBranch'); cy.log('Hello ' + useAppli ? 'Appli' : 'image-snapshot'); const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-'); diff --git a/cypress/integration/rendering/sequencediagram.spec.js b/cypress/integration/rendering/sequencediagram.spec.js index c110f05ada9..aaf5e94ceb2 100644 --- a/cypress/integration/rendering/sequencediagram.spec.js +++ b/cypress/integration/rendering/sequencediagram.spec.js @@ -80,7 +80,7 @@ context('Sequence diagram', () => { loop Loopy Bob->>Alice: Pasten end `, - {} + { wrap: true } ); }); context('font settings', () => { diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index f9d75eb234b..0d870e1a369 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -64,7 +64,7 @@ commit commit
-
+
sequenceDiagram title: My Sequence Diagram Title accTitle: My Acc Sequence Diagram @@ -218,20 +218,41 @@ }
-graph LR - A[[subroutine shape test]] - A -->|Get money| B[[Go shopping]] - B --> C[[Let me think...
Do I want something for work,
something to spend every free second with,
or something to get around?]] - C -->|One| D[[Laptop]] - C -->|Two| E[[iPhone]] - C -->|Three| F[[Car
wroom wroom]] - click A "index.html#link-clicked" "link test" - click B testClick "click test" - classDef someclass fill:#f96; - class A someclass; - class C someclass; +%%{init: {'config': {'wrap': true }}}%% + sequenceDiagram + participant A as Extremely utterly long line of longness which had previously overflown the actor box as it is much longer than what it should be + A->>Bob: Hola + Bob-->A: Pasten !
+ gitGraph + commit id: "ZERO" + branch develop + commit id:"A" + checkout main + commit id:"ONE" + checkout develop + commit id:"B" + branch featureA + commit id:"FIX" + commit id: "FIX-2" + checkout main + commit id:"TWO" + cherry-pick id:"A" + commit id:"THREE" + cherry-pick id:"FIX" + checkout develop + commit id:"C" + merge featureA +
+
+flowchart TD + A[Christmas] -->|Get money| B(Go shopping) + B --> C{Let me think} + C -->|One| D[Laptop] + C -->|Two| E[iPhone] + C -->|Three| F[fa:fa-car Car] +
classDiagram Animal "1" <|-- Duck Animal <|-- Fish @@ -292,7 +313,8 @@ htmlLabels: true, }, sequence: { - mirrorActors: false, + // mirrorActors: false,' + wrap: false, }, // gantt: { axisFormat: '%m/%d/%Y' }, // sequence: { @@ -315,6 +337,7 @@ curve: 'cardinal', // securityLevel: 'sandbox', // themeVariables: {relationLabelColor: 'red'} + wrap: true, }); function callback() { alert('It worked'); diff --git a/docs/Setup.md b/docs/Setup.md index 9408b8e90ec..85070a1e723 100644 --- a/docs/Setup.md +++ b/docs/Setup.md @@ -1429,15 +1429,6 @@ function _Default value: At default, will mirror Global Config_ Returns **[object][5]** The siteConfig -## parse - -### Parameters - -- `text` -- `dia` - -Returns **any** - ## getSiteConfig ## getSiteConfig @@ -1480,21 +1471,6 @@ Returns **any** The currentConfig merged with the sanitized conf Returns **any** The currentConfig -## sanitize - -## sanitize - -| Function | Description | Type | Values | -| -------- | -------------------------------------- | ----------- | ------ | -| sanitize | Sets the siteConfig to desired values. | Put Request | None | - -Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies -options in-place - -### Parameters - -- `options` **any** The potential setConfig parameter - ## render Function that renders an svg with a graph from a chart definition. Usage example below. @@ -1523,6 +1499,21 @@ $(function () { Returns **any** +## sanitize + +## sanitize + +| Function | Description | Type | Values | +| -------- | -------------------------------------- | ----------- | ------ | +| sanitize | Sets the siteConfig to desired values. | Put Request | None | + +Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies +options in-place + +### Parameters + +- `options` **any** The potential setConfig parameter + ## addDirective Pushes in a directive to the configuration @@ -1533,6 +1524,8 @@ Pushes in a directive to the configuration ## reset +## reset + | Function | Description | Type | Required | Values | | -------- | ---------------------------- | ----------- | -------- | ------ | | reset | Resets currentConfig to conf | Put Request | Required | None | diff --git a/src/diagram-api/diagram-orchestration.js b/src/diagram-api/diagram-orchestration.js index 51f1c43db92..d73bc1bbba0 100644 --- a/src/diagram-api/diagram-orchestration.js +++ b/src/diagram-api/diagram-orchestration.js @@ -19,13 +19,14 @@ import gitGraphDetector from '../diagrams/git/gitGraphDetector'; // mindmapRenderer, // mindmapDetector // ); -registerDiagram( - 'gitGraph', - gitGraphParser, - gitGraphDb, - gitGraphRenderer, - undefined, - gitGraphDetector -); -const apa = { apa: 1 }; -export default apa; +const addDiagrams = () => { + registerDiagram( + 'gitGraph', + gitGraphParser, + gitGraphDb, + gitGraphRenderer, + undefined, + gitGraphDetector + ); +}; +export default addDiagrams; diff --git a/src/diagram-api/diagramAPI.js b/src/diagram-api/diagramAPI.js index 176a2bef9de..62c8843682f 100644 --- a/src/diagram-api/diagramAPI.js +++ b/src/diagram-api/diagramAPI.js @@ -79,7 +79,7 @@ const diagrams = { flowDb.setGen('gen-1'); }, }, - flowchartV2: { + 'flowchart-v2': { db: flowDb, renderer: flowRendererV2, parser: flowParser, diff --git a/src/diagrams/sequence/sequenceDb.js b/src/diagrams/sequence/sequenceDb.js index 8ae5fe8f109..7d030912774 100644 --- a/src/diagrams/sequence/sequenceDb.js +++ b/src/diagrams/sequence/sequenceDb.js @@ -19,7 +19,7 @@ const notes = []; let diagramTitle = ''; let description = ''; let sequenceNumbersEnabled = false; -let wrapEnabled = false; +let wrapEnabled; export const parseDirective = function (statement, context, type) { mermaidAPI.parseDirective(this, statement, context, type); diff --git a/src/diagrams/sequence/svgDraw.js b/src/diagrams/sequence/svgDraw.js index a00d10169f8..cbd4244a5ed 100644 --- a/src/diagrams/sequence/svgDraw.js +++ b/src/diagrams/sequence/svgDraw.js @@ -847,9 +847,12 @@ const _drawTextCandidateFunc = (function () { function byTspan(content, g, x, y, width, height, textAttrs, conf) { const { actorFontSize, actorFontFamily, actorFontWeight } = conf; + let _actorFontSize = + actorFontSize && actorFontSize.replace ? actorFontSize.replace('px', '') : actorFontSize; + const lines = content.split(common.lineBreakRegex); for (let i = 0; i < lines.length; i++) { - const dy = i * actorFontSize - (actorFontSize * (lines.length - 1)) / 2; + const dy = i * _actorFontSize - (_actorFontSize * (lines.length - 1)) / 2; const text = g .append('text') .attr('x', x + width / 2) diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 9c45a2bf2ec..5b16c609a4f 100644 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -19,7 +19,7 @@ import { select } from 'd3'; import { compile, serialize, stringify } from 'stylis'; import pkg from '../package.json'; import * as configApi from './config'; -import apa from './diagram-api/diagram-orchestration'; +import addDiagrams from './diagram-api/diagram-orchestration'; import classDb from './diagrams/class/classDb'; import flowDb from './diagrams/flowchart/flowDb'; import flowRenderer from './diagrams/flowchart/flowRenderer'; @@ -515,6 +515,7 @@ function initialize(options) { updateRendererConfigs(config); setLogLevel(config.logLevel); + addDiagrams(); } const mermaidAPI = Object.freeze({ From 1ed926b491b2eafd4bf56205971c447599f2418e Mon Sep 17 00:00:00 2001 From: mmorel-35 Date: Mon, 25 Jul 2022 07:03:51 +0000 Subject: [PATCH 07/13] chore: update browsers list --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b49cb0ee22b..b1abfe0fca7 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "webpack-merge": "^5.8.0", "webpack-node-externals": "^3.0.0" }, - "resolutions": { + "resolutions": { "d3": "^7.0.0" }, "files": [ diff --git a/yarn.lock b/yarn.lock index 853d09418e3..2797ab81bda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3452,9 +3452,9 @@ camelcase@^6.2.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001359: - version "1.0.30001367" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz" - integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== + version "1.0.30001370" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001370.tgz" + integrity sha512-3PDmaP56wz/qz7G508xzjx8C+MC2qEm4SYhSEzC9IBROo+dGXFWRuaXkWti0A9tuI00g+toiriVqxtWMgl350g== caseless@~0.12.0: version "0.12.0" From c40368b0fa9b21a019bfd8ad0f0f0e40fbb4a0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorens=20Le=C3=B3n?= Date: Tue, 12 Jul 2022 17:55:43 +0200 Subject: [PATCH 08/13] fix: remove right padding when a label contains HTML entities Decode the HTML entities from the label text before adding them to the HTML this prevents a miss-calculation of the label text length --- .../integration/rendering/stateDiagram-v2.spec.js | 12 ++++++++++++ src/dagre-wrapper/createLabel.js | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index b5ab8644001..946b5d31ef4 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -509,4 +509,16 @@ stateDiagram-v2 expect(svg).to.not.have.attr('style'); }); }); + + it('v2 should render a state diagram and set the correct length of the labels', () => { + imgSnapshotTest( + ` + stateDiagram-v2 + [*] --> 1 + 1 --> 2: test({ foo#colon; 'far' }) + 2 --> [*] + `, + { logLevel: 0, fontFamily: 'courier' } + ); + }); }); diff --git a/src/dagre-wrapper/createLabel.js b/src/dagre-wrapper/createLabel.js index ed7b9f6fb11..3e3ffdfc956 100644 --- a/src/dagre-wrapper/createLabel.js +++ b/src/dagre-wrapper/createLabel.js @@ -2,6 +2,7 @@ import { select } from 'd3'; import { log } from '../logger'; // eslint-disable-line import { getConfig } from '../config'; import { sanitizeText, evaluate } from '../diagrams/common/common'; +import { decodeEntities } from '../mermaidAPI'; const sanitizeTxt = (txt) => sanitizeText(txt, getConfig()); @@ -52,7 +53,7 @@ const createLabel = (_vertexText, style, isTitle, isNode) => { log.info('vertexText' + vertexText); const node = { isNode, - label: vertexText.replace( + label: decodeEntities(vertexText).replace( /fa[lrsb]?:fa-[\w-]+/g, (s) => `` ), From f7c5e1b8b2e5295b959be2e1d2c8ccdbb86f3ec4 Mon Sep 17 00:00:00 2001 From: mmorel-35 Date: Mon, 1 Aug 2022 07:07:51 +0000 Subject: [PATCH 09/13] chore: update browsers list --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2797ab81bda..f9b1641c61a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3452,9 +3452,9 @@ camelcase@^6.2.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001359: - version "1.0.30001370" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001370.tgz" - integrity sha512-3PDmaP56wz/qz7G508xzjx8C+MC2qEm4SYhSEzC9IBROo+dGXFWRuaXkWti0A9tuI00g+toiriVqxtWMgl350g== + version "1.0.30001373" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz" + integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ== caseless@~0.12.0: version "0.12.0" From 81ff4416dc829a18bc30bee8f90308bdfd1bd700 Mon Sep 17 00:00:00 2001 From: Muhammad Faisal Bin Arba'in Date: Sat, 18 Jun 2022 17:59:24 +0800 Subject: [PATCH 10/13] rotate class id when branch more than 8 --- src/diagrams/git/gitGraphRenderer.js | 29 +++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/diagrams/git/gitGraphRenderer.js b/src/diagrams/git/gitGraphRenderer.js index 1d94f7c5e7d..5dc05c902d5 100644 --- a/src/diagrams/git/gitGraphRenderer.js +++ b/src/diagrams/git/gitGraphRenderer.js @@ -15,6 +15,8 @@ const commitType = { CHERRY_PICK: 4, }; +const THEME_SIZE = 8; + let branchPos = {}; let commitPos = {}; let lanes = []; @@ -120,7 +122,7 @@ const drawCommits = (svg, commits, modifyGraph) => { 'commit ' + commit.id + ' commit-highlight' + - branchPos[commit.branch].index + + (branchPos[commit.branch].index % THEME_SIZE) + ' ' + typeClass + '-outer' @@ -136,7 +138,7 @@ const drawCommits = (svg, commits, modifyGraph) => { 'commit ' + commit.id + ' commit' + - branchPos[commit.branch].index + + (branchPos[commit.branch].index % THEME_SIZE) + ' ' + typeClass + '-inner' @@ -183,7 +185,10 @@ const drawCommits = (svg, commits, modifyGraph) => { circle.attr('cx', x); circle.attr('cy', y); circle.attr('r', commit.type === commitType.MERGE ? 9 : 10); - circle.attr('class', 'commit ' + commit.id + ' commit' + branchPos[commit.branch].index); + circle.attr( + 'class', + 'commit ' + commit.id + ' commit' + (branchPos[commit.branch].index % THEME_SIZE) + ); if (commit.type === commitType.MERGE) { const circle2 = gBullets.append('circle'); circle2.attr('cx', x); @@ -191,7 +196,12 @@ const drawCommits = (svg, commits, modifyGraph) => { circle2.attr('r', 6); circle2.attr( 'class', - 'commit ' + typeClass + ' ' + commit.id + ' commit' + branchPos[commit.branch].index + 'commit ' + + typeClass + + ' ' + + commit.id + + ' commit' + + (branchPos[commit.branch].index % THEME_SIZE) ); } if (commit.type === commitType.REVERSE) { @@ -200,7 +210,12 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('d', `M ${x - 5},${y - 5}L${x + 5},${y + 5}M${x - 5},${y + 5}L${x + 5},${y - 5}`) .attr( 'class', - 'commit ' + typeClass + ' ' + commit.id + ' commit' + branchPos[commit.branch].index + 'commit ' + + typeClass + + ' ' + + commit.id + + ' commit' + + (branchPos[commit.branch].index % THEME_SIZE) ); } } @@ -430,7 +445,7 @@ const drawArrow = (svg, commit1, commit2, allCommits) => { const arrow = svg .append('path') .attr('d', lineDef) - .attr('class', 'arrow arrow' + colorClassNum); + .attr('class', 'arrow arrow' + (colorClassNum % THEME_SIZE)); }; const drawArrows = (svg, commits) => { @@ -460,7 +475,7 @@ const drawBranches = (svg, branches) => { const gitGraphConfig = getConfig().gitGraph; const g = svg.append('g'); branches.forEach((branch, index) => { - let adjustIndexForTheme = index >= 8 ? index - 8 : index; + let adjustIndexForTheme = index % THEME_SIZE; const pos = branchPos[branch.name].pos; const line = g.append('line'); From 91e369a840cf3bdfad906765f482da9144a4c303 Mon Sep 17 00:00:00 2001 From: Muhammad Faisal Bin Arba'in Date: Mon, 20 Jun 2022 00:02:47 +0800 Subject: [PATCH 11/13] rename const name --- src/diagrams/git/gitGraphRenderer.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diagrams/git/gitGraphRenderer.js b/src/diagrams/git/gitGraphRenderer.js index 5dc05c902d5..bc6d1a8a363 100644 --- a/src/diagrams/git/gitGraphRenderer.js +++ b/src/diagrams/git/gitGraphRenderer.js @@ -15,7 +15,7 @@ const commitType = { CHERRY_PICK: 4, }; -const THEME_SIZE = 8; +const THEME_COLOR_LIMIT = 8; let branchPos = {}; let commitPos = {}; @@ -122,7 +122,7 @@ const drawCommits = (svg, commits, modifyGraph) => { 'commit ' + commit.id + ' commit-highlight' + - (branchPos[commit.branch].index % THEME_SIZE) + + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + ' ' + typeClass + '-outer' @@ -138,7 +138,7 @@ const drawCommits = (svg, commits, modifyGraph) => { 'commit ' + commit.id + ' commit' + - (branchPos[commit.branch].index % THEME_SIZE) + + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + ' ' + typeClass + '-inner' @@ -187,7 +187,7 @@ const drawCommits = (svg, commits, modifyGraph) => { circle.attr('r', commit.type === commitType.MERGE ? 9 : 10); circle.attr( 'class', - 'commit ' + commit.id + ' commit' + (branchPos[commit.branch].index % THEME_SIZE) + 'commit ' + commit.id + ' commit' + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) ); if (commit.type === commitType.MERGE) { const circle2 = gBullets.append('circle'); @@ -201,7 +201,7 @@ const drawCommits = (svg, commits, modifyGraph) => { ' ' + commit.id + ' commit' + - (branchPos[commit.branch].index % THEME_SIZE) + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) ); } if (commit.type === commitType.REVERSE) { @@ -215,7 +215,7 @@ const drawCommits = (svg, commits, modifyGraph) => { ' ' + commit.id + ' commit' + - (branchPos[commit.branch].index % THEME_SIZE) + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) ); } } @@ -445,7 +445,7 @@ const drawArrow = (svg, commit1, commit2, allCommits) => { const arrow = svg .append('path') .attr('d', lineDef) - .attr('class', 'arrow arrow' + (colorClassNum % THEME_SIZE)); + .attr('class', 'arrow arrow' + (colorClassNum % THEME_COLOR_LIMIT)); }; const drawArrows = (svg, commits) => { @@ -475,7 +475,7 @@ const drawBranches = (svg, branches) => { const gitGraphConfig = getConfig().gitGraph; const g = svg.append('g'); branches.forEach((branch, index) => { - let adjustIndexForTheme = index % THEME_SIZE; + let adjustIndexForTheme = index % THEME_COLOR_LIMIT; const pos = branchPos[branch.name].pos; const line = g.append('line'); From 846531363eebace28d9dc7f51a3974eefd996d2e Mon Sep 17 00:00:00 2001 From: Muhammad Faisal Bin Arba'in Date: Fri, 24 Jun 2022 01:15:39 +0800 Subject: [PATCH 12/13] PR comments --- src/diagrams/git/gitGraphRenderer.js | 52 ++++++++++------------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/src/diagrams/git/gitGraphRenderer.js b/src/diagrams/git/gitGraphRenderer.js index bc6d1a8a363..0a7c457cf72 100644 --- a/src/diagrams/git/gitGraphRenderer.js +++ b/src/diagrams/git/gitGraphRenderer.js @@ -119,13 +119,9 @@ const drawCommits = (svg, commits, modifyGraph) => { circle.attr('width', 20); circle.attr( 'class', - 'commit ' + - commit.id + - ' commit-highlight' + - (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + - ' ' + - typeClass + - '-outer' + `commit ${commit.id} commit-highlight${ + branchPos[commit.branch].index % THEME_COLOR_LIMIT + } ${typeClass}-outer` ); gBullets .append('rect') @@ -135,13 +131,9 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('width', 12) .attr( 'class', - 'commit ' + - commit.id + - ' commit' + - (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + - ' ' + - typeClass + - '-inner' + `commit ${commit.id} commit${ + branchPos[commit.branch].index % THEME_COLOR_LIMIT + } ${typeClass}-inner` ); } else if (commit.type === commitType.CHERRY_PICK) { gBullets @@ -149,21 +141,21 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('cx', x) .attr('cy', y) .attr('r', 10) - .attr('class', 'commit ' + commit.id + ' ' + typeClass); + .attr('class', `commit ${commit.id} ${typeClass}`); gBullets .append('circle') .attr('cx', x - 3) .attr('cy', y + 2) .attr('r', 2.75) .attr('fill', '#fff') - .attr('class', 'commit ' + commit.id + ' ' + typeClass); + .attr('class', `commit ${commit.id} ${typeClass}`); gBullets .append('circle') .attr('cx', x + 3) .attr('cy', y + 2) .attr('r', 2.75) .attr('fill', '#fff') - .attr('class', 'commit ' + commit.id + ' ' + typeClass); + .attr('class', `commit ${commit.id} ${typeClass}`); gBullets .append('line') .attr('x1', x + 3) @@ -171,7 +163,7 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('x2', x) .attr('y2', y - 5) .attr('stroke', '#fff') - .attr('class', 'commit ' + commit.id + ' ' + typeClass); + .attr('class', `commit ${commit.id} ${typeClass}`); gBullets .append('line') .attr('x1', x - 3) @@ -179,7 +171,7 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('x2', x) .attr('y2', y - 5) .attr('stroke', '#fff') - .attr('class', 'commit ' + commit.id + ' ' + typeClass); + .attr('class', `commit ${commit.id} ${typeClass}`); } else { const circle = gBullets.append('circle'); circle.attr('cx', x); @@ -187,7 +179,7 @@ const drawCommits = (svg, commits, modifyGraph) => { circle.attr('r', commit.type === commitType.MERGE ? 9 : 10); circle.attr( 'class', - 'commit ' + commit.id + ' commit' + (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + `commit ${commit.id} commit${branchPos[commit.branch].index % THEME_COLOR_LIMIT}` ); if (commit.type === commitType.MERGE) { const circle2 = gBullets.append('circle'); @@ -196,12 +188,9 @@ const drawCommits = (svg, commits, modifyGraph) => { circle2.attr('r', 6); circle2.attr( 'class', - 'commit ' + - typeClass + - ' ' + - commit.id + - ' commit' + - (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + `commit ${typeClass} ${commit.id} commit${ + branchPos[commit.branch].index % THEME_COLOR_LIMIT + }` ); } if (commit.type === commitType.REVERSE) { @@ -210,12 +199,9 @@ const drawCommits = (svg, commits, modifyGraph) => { .attr('d', `M ${x - 5},${y - 5}L${x + 5},${y + 5}M${x - 5},${y + 5}L${x + 5},${y - 5}`) .attr( 'class', - 'commit ' + - typeClass + - ' ' + - commit.id + - ' commit' + - (branchPos[commit.branch].index % THEME_COLOR_LIMIT) + `commit ${typeClass} ${commit.id} commit${ + branchPos[commit.branch].index % THEME_COLOR_LIMIT + }` ); } } @@ -475,7 +461,7 @@ const drawBranches = (svg, branches) => { const gitGraphConfig = getConfig().gitGraph; const g = svg.append('g'); branches.forEach((branch, index) => { - let adjustIndexForTheme = index % THEME_COLOR_LIMIT; + const adjustIndexForTheme = index % THEME_COLOR_LIMIT; const pos = branchPos[branch.name].pos; const line = g.append('line'); From 9ee43c0b7a9b52108cf75ae291941e7f0ca7f78d Mon Sep 17 00:00:00 2001 From: Muhammad Faisal Bin Arba'in Date: Fri, 24 Jun 2022 07:35:00 +0800 Subject: [PATCH 13/13] snapshot test for more 8 branches with commits --- .../integration/rendering/gitGraph.spec.js | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cypress/integration/rendering/gitGraph.spec.js b/cypress/integration/rendering/gitGraph.spec.js index 4dda2c16edc..283a52c67c4 100644 --- a/cypress/integration/rendering/gitGraph.spec.js +++ b/cypress/integration/rendering/gitGraph.spec.js @@ -207,4 +207,50 @@ describe('Git Graph diagram', () => { {} ); }); + + it('12: should render commits for more than 8 branches', () => { + imgSnapshotTest( + ` + gitGraph + checkout main + commit + checkout main + branch branch1 + commit + checkout main + merge branch1 + branch branch2 + commit + checkout main + merge branch2 + branch branch3 + commit + checkout main + merge branch3 + branch branch4 + commit + checkout main + merge branch4 + branch branch5 + commit + checkout main + merge branch5 + branch branch6 + commit + checkout main + merge branch6 + branch branch7 + commit + checkout main + merge branch7 + branch branch8 + commit + checkout main + merge branch8 + branch branch9 + commit + `, + {} + ); + }); });