Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Knut Sveidqvist 2021-11-30 19:24:10 +01:00
commit a018789026
106 changed files with 3032 additions and 2965 deletions

View File

@ -1 +1,2 @@
**/*.spec.js
dist/**
.github/**

View File

@ -2,6 +2,7 @@
"env": {
"browser": true,
"es6": true,
"jest/globals": true,
"node": true
},
"parser": "@babel/eslint-parser",
@ -13,8 +14,10 @@
"sourceType": "module"
},
"extends": ["eslint:recommended", "plugin:jsdoc/recommended", "plugin:prettier/recommended"],
"plugins": ["jsdoc", "prettier"],
"plugins": ["jest", "jsdoc", "prettier"],
"rules": {
"no-prototype-builtins": 0,
"no-unused-vars": 0,
"jsdoc/check-indentation": 0,
"jsdoc/check-alignment": 0,
"jsdoc/check-line-alignment": 0,

View File

@ -1,13 +0,0 @@
name: Lock closed issue
on:
issues:
types: [closed]
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: Dunning-Kruger/lock-issues@v1.1
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -0,0 +1,13 @@
name: Validate PR Labeler Configuration
on: [push, pull_request]
jobs:
pr-labeler:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2.3.4
- name: Validate Configuration
uses: Yash-Singh1/pr-labeler-config-validator@releases/v0.0.3
with:
configuration-path: .github/pr-labeler.yml

View File

@ -1,6 +1,8 @@
{
"endOfLine": "auto",
"plugins": ["prettier-plugin-jsdoc"],
"plugins": [
"prettier-plugin-jsdoc"
],
"printWidth": 100,
"singleQuote": true
}
}

View File

@ -1,3 +1,3 @@
export const curveBasis = 'basis'
export const curveLinear = 'linear'
export const curveCardinal = 'cardinal'
export const curveBasis = 'basis';
export const curveLinear = 'linear';
export const curveCardinal = 'cardinal';

71
__mocks__/d3.js vendored
View File

@ -1,11 +1,10 @@
/* eslint-env jest */
let NewD3 = function () {
function returnThis () {
return this
function returnThis() {
return this;
}
return {
append: function () {
return NewD3()
return NewD3();
},
lower: returnThis,
attr: returnThis,
@ -16,41 +15,47 @@ let NewD3 = function () {
getBBox: function () {
return {
height: 10,
width: 20
}
}
}
}
}
}
width: 20,
};
},
},
},
};
};
export const select = function () {
return new NewD3()
}
return new NewD3();
};
export const selectAll = function () {
return new NewD3()
}
return new NewD3();
};
export const curveBasis = 'basis'
export const curveLinear = 'linear'
export const curveCardinal = 'cardinal'
export const curveBasis = 'basis';
export const curveLinear = 'linear';
export const curveCardinal = 'cardinal';
export const MockD3 = (name, parent) => {
const children = []
const children = [];
const elem = {
get __children () { return children },
get __name () { return name },
get __parent () { return parent }
}
get __children() {
return children;
},
get __name() {
return name;
},
get __parent() {
return parent;
},
};
elem.append = (name) => {
const mockElem = MockD3(name, elem)
children.push(mockElem)
return mockElem
}
elem.lower = jest.fn(() => elem)
elem.attr = jest.fn(() => elem)
elem.text = jest.fn(() => elem)
elem.style = jest.fn(() => elem)
return elem
}
const mockElem = MockD3(name, elem);
children.push(mockElem);
return mockElem;
};
elem.lower = jest.fn(() => elem);
elem.attr = jest.fn(() => elem);
elem.text = jest.fn(() => elem);
elem.style = jest.fn(() => elem);
return elem;
};

View File

@ -1 +1,3 @@
{ "video": false }
{
"video": false
}

10
cypress/.eslintrc.json Normal file
View File

@ -0,0 +1,10 @@
{
"env": {
"cypress/globals": true
},
"extends": ["plugin:cypress/recommended"],
"plugins": ["cypress"],
"rules":{
"cypress/no-unnecessary-waiting": 0
}
}

View File

@ -2,15 +2,16 @@
context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
cy.visit('https://example.cypress.io/commands/actions');
});
// https://on.cypress.io/interacting-with-elements
it('.type() - type into a DOM element', () => {
// https://on.cypress.io/type
cy.get('.action-email')
.type('fake@email.com').should('have.value', 'fake@email.com')
.type('fake@email.com')
.should('have.value', 'fake@email.com')
// .type() with special character sequences
.type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
@ -24,48 +25,52 @@ context('Actions', () => {
// Delay each keypress by 0.1 sec
.type('slow.typing@email.com', { delay: 100 })
.should('have.value', 'slow.typing@email.com')
.should('have.value', 'slow.typing@email.com');
cy.get('.action-disabled')
// Ignore error checking prior to type
// like whether the input is visible or disabled
.type('disabled error checking', { force: true })
.should('have.value', 'disabled error checking')
})
.should('have.value', 'disabled error checking');
});
it('.focus() - focus on a DOM element', () => {
// https://on.cypress.io/focus
cy.get('.action-focus').focus()
cy.get('.action-focus')
.focus()
.should('have.class', 'focus')
.prev().should('have.attr', 'style', 'color: orange;')
})
.prev()
.should('have.attr', 'style', 'color: orange;');
});
it('.blur() - blur off a DOM element', () => {
// https://on.cypress.io/blur
cy.get('.action-blur').type('About to blur').blur()
cy.get('.action-blur')
.type('About to blur')
.blur()
.should('have.class', 'error')
.prev().should('have.attr', 'style', 'color: red;')
})
.prev()
.should('have.attr', 'style', 'color: red;');
});
it('.clear() - clears an input or textarea element', () => {
// https://on.cypress.io/clear
cy.get('.action-clear').type('Clear this text')
cy.get('.action-clear')
.type('Clear this text')
.should('have.value', 'Clear this text')
.clear()
.should('have.value', '')
})
.should('have.value', '');
});
it('.submit() - submit a form', () => {
// https://on.cypress.io/submit
cy.get('.action-form')
.find('[type="text"]').type('HALFOFF')
cy.get('.action-form').submit()
.next().should('contain', 'Your form has been submitted!')
})
cy.get('.action-form').find('[type="text"]').type('HALFOFF');
cy.get('.action-form').submit().next().should('contain', 'Your form has been submitted!');
});
it('.click() - click on a DOM element', () => {
// https://on.cypress.io/click
cy.get('.action-btn').click()
cy.get('.action-btn').click();
// You can click on 9 specific positions of an element:
// -----------------------------------
@ -81,16 +86,16 @@ context('Actions', () => {
// -----------------------------------
// clicking in the center of the element is the default
cy.get('#action-canvas').click()
cy.get('#action-canvas').click();
cy.get('#action-canvas').click('topLeft')
cy.get('#action-canvas').click('top')
cy.get('#action-canvas').click('topRight')
cy.get('#action-canvas').click('left')
cy.get('#action-canvas').click('right')
cy.get('#action-canvas').click('bottomLeft')
cy.get('#action-canvas').click('bottom')
cy.get('#action-canvas').click('bottomRight')
cy.get('#action-canvas').click('topLeft');
cy.get('#action-canvas').click('top');
cy.get('#action-canvas').click('topRight');
cy.get('#action-canvas').click('left');
cy.get('#action-canvas').click('right');
cy.get('#action-canvas').click('bottomLeft');
cy.get('#action-canvas').click('bottom');
cy.get('#action-canvas').click('bottomRight');
// .click() accepts an x and y coordinate
// that controls where the click occurs :)
@ -102,90 +107,83 @@ context('Actions', () => {
.click(100, 185)
.click(125, 190)
.click(150, 185)
.click(170, 165)
.click(170, 165);
// click multiple elements by passing multiple: true
cy.get('.action-labels>.label').click({ multiple: true })
cy.get('.action-labels>.label').click({ multiple: true });
// Ignore error checking prior to clicking
cy.get('.action-opacity>.btn').click({ force: true })
})
cy.get('.action-opacity>.btn').click({ force: true });
});
it('.dblclick() - double click on a DOM element', () => {
// https://on.cypress.io/dblclick
// Our app has a listener on 'dblclick' event in our 'scripts.js'
// that hides the div and shows an input on double click
cy.get('.action-div').dblclick().should('not.be.visible')
cy.get('.action-input-hidden').should('be.visible')
})
cy.get('.action-div').dblclick().should('not.be.visible');
cy.get('.action-input-hidden').should('be.visible');
});
it('.check() - check a checkbox or radio element', () => {
// https://on.cypress.io/check
// By default, .check() will check all
// matching checkbox or radio elements in succession, one after another
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
.check().should('be.checked')
cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').check().should('be.checked');
cy.get('.action-radios [type="radio"]').not('[disabled]')
.check().should('be.checked')
cy.get('.action-radios [type="radio"]').not('[disabled]').check().should('be.checked');
// .check() accepts a value argument
cy.get('.action-radios [type="radio"]')
.check('radio1').should('be.checked')
cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked');
// .check() accepts an array of values
cy.get('.action-multiple-checkboxes [type="checkbox"]')
.check(['checkbox1', 'checkbox2']).should('be.checked')
.check(['checkbox1', 'checkbox2'])
.should('be.checked');
// Ignore error checking prior to checking
cy.get('.action-checkboxes [disabled]')
.check({ force: true }).should('be.checked')
cy.get('.action-checkboxes [disabled]').check({ force: true }).should('be.checked');
cy.get('.action-radios [type="radio"]')
.check('radio3', { force: true }).should('be.checked')
})
cy.get('.action-radios [type="radio"]').check('radio3', { force: true }).should('be.checked');
});
it('.uncheck() - uncheck a checkbox element', () => {
// https://on.cypress.io/uncheck
// By default, .uncheck() will uncheck all matching
// checkbox elements in succession, one after another
cy.get('.action-check [type="checkbox"]')
.not('[disabled]')
.uncheck().should('not.be.checked')
cy.get('.action-check [type="checkbox"]').not('[disabled]').uncheck().should('not.be.checked');
// .uncheck() accepts a value argument
cy.get('.action-check [type="checkbox"]')
.check('checkbox1')
.uncheck('checkbox1').should('not.be.checked')
.uncheck('checkbox1')
.should('not.be.checked');
// .uncheck() accepts an array of values
cy.get('.action-check [type="checkbox"]')
.check(['checkbox1', 'checkbox3'])
.uncheck(['checkbox1', 'checkbox3']).should('not.be.checked')
.uncheck(['checkbox1', 'checkbox3'])
.should('not.be.checked');
// Ignore error checking prior to unchecking
cy.get('.action-check [disabled]')
.uncheck({ force: true }).should('not.be.checked')
})
cy.get('.action-check [disabled]').uncheck({ force: true }).should('not.be.checked');
});
it('.select() - select an option in a <select> element', () => {
// https://on.cypress.io/select
// Select option(s) with matching text content
cy.get('.action-select').select('apples')
cy.get('.action-select').select('apples');
cy.get('.action-select-multiple')
.select(['apples', 'oranges', 'bananas'])
cy.get('.action-select-multiple').select(['apples', 'oranges', 'bananas']);
// Select option(s) with matching value
cy.get('.action-select').select('fr-bananas')
cy.get('.action-select').select('fr-bananas');
cy.get('.action-select-multiple')
.select(['fr-apples', 'fr-oranges', 'fr-bananas'])
})
cy.get('.action-select-multiple').select(['fr-apples', 'fr-oranges', 'fr-bananas']);
});
it('.scrollIntoView() - scroll an element into view', () => {
// https://on.cypress.io/scrollintoview
@ -194,27 +192,21 @@ context('Actions', () => {
// because they're not within
// the viewable area of their parent
// (we need to scroll to see them)
cy.get('#scroll-horizontal button')
.should('not.be.visible')
cy.get('#scroll-horizontal button').should('not.be.visible');
// scroll the button into view, as if the user had scrolled
cy.get('#scroll-horizontal button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-horizontal button').scrollIntoView().should('be.visible');
cy.get('#scroll-vertical button')
.should('not.be.visible')
cy.get('#scroll-vertical button').should('not.be.visible');
// Cypress handles the scroll direction needed
cy.get('#scroll-vertical button').scrollIntoView()
.should('be.visible')
cy.get('#scroll-vertical button').scrollIntoView().should('be.visible');
cy.get('#scroll-both button')
.should('not.be.visible')
cy.get('#scroll-both button').should('not.be.visible');
// Cypress knows to scroll to the right and down
cy.get('#scroll-both button').scrollIntoView()
.should('be.visible')
})
cy.get('#scroll-both button').scrollIntoView().should('be.visible');
});
it('.trigger() - trigger an event on a DOM element', () => {
// https://on.cypress.io/trigger
@ -228,12 +220,12 @@ context('Actions', () => {
cy.get('.trigger-input-range')
.invoke('val', 25)
.trigger('change')
.get('input[type=range]').siblings('p')
.should('have.text', '25')
})
.get('input[type=range]')
.siblings('p')
.should('have.text', '25');
});
it('cy.scrollTo() - scroll the window or element to a position', () => {
// https://on.cypress.io/scrollTo
// You can scroll to 9 specific positions of an element:
@ -251,22 +243,22 @@ context('Actions', () => {
// if you chain .scrollTo() off of cy, we will
// scroll the entire window
cy.scrollTo('bottom')
cy.scrollTo('bottom');
cy.get('#scrollable-horizontal').scrollTo('right')
cy.get('#scrollable-horizontal').scrollTo('right');
// or you can scroll to a specific coordinate:
// (x axis, y axis) in pixels
cy.get('#scrollable-vertical').scrollTo(250, 250)
cy.get('#scrollable-vertical').scrollTo(250, 250);
// or you can scroll to a specific percentage
// of the (width, height) of the element
cy.get('#scrollable-both').scrollTo('75%', '25%')
cy.get('#scrollable-both').scrollTo('75%', '25%');
// control the easing of the scroll (default is 'swing')
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' })
cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' });
// control the duration of the scroll (in ms)
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 })
})
})
cy.get('#scrollable-both').scrollTo('center', { duration: 2000 });
});
});

View File

@ -2,8 +2,8 @@
context('Aliasing', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/aliasing')
})
cy.visit('https://example.cypress.io/commands/aliasing');
});
it('.as() - alias a DOM element for later use', () => {
// https://on.cypress.io/as
@ -12,31 +12,25 @@ context('Aliasing', () => {
// We don't have to traverse to the element
// later in our code, we reference it with @
cy.get('.as-table').find('tbody>tr')
.first().find('td').first()
.find('button').as('firstBtn')
cy.get('.as-table').find('tbody>tr').first().find('td').first().find('button').as('firstBtn');
// when we reference the alias, we place an
// @ in front of its name
cy.get('@firstBtn').click()
cy.get('@firstBtn').click();
cy.get('@firstBtn')
.should('have.class', 'btn-success')
.and('contain', 'Changed')
})
cy.get('@firstBtn').should('have.class', 'btn-success').and('contain', 'Changed');
});
it('.as() - alias a route for later use', () => {
// Alias the route to wait for its response
cy.server()
cy.route('GET', 'comments/*').as('getComment')
cy.server();
cy.route('GET', 'comments/*').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
cy.get('.network-btn').click();
// https://on.cypress.io/wait
cy.wait('@getComment').its('status').should('eq', 200)
})
})
cy.wait('@getComment').its('status').should('eq', 200);
});
});

View File

@ -2,8 +2,8 @@
context('Assertions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/assertions')
})
cy.visit('https://example.cypress.io/commands/assertions');
});
describe('Implicit Assertions', () => {
it('.should() - make an assertion about the current subject', () => {
@ -23,7 +23,7 @@ context('Assertions', () => {
// first need to invoke jQuery method text()
// and then match using regular expression
.invoke('text')
.should('match', /column content/i)
.should('match', /column content/i);
// a better way to check element's text content against a regular expression
// is to use "cy.contains"
@ -32,33 +32,33 @@ context('Assertions', () => {
.find('tbody tr:last')
// finds first <td> element with text content matching regular expression
.contains('td', /column content/i)
.should('be.visible')
.should('be.visible');
// for more information about asserting element's text
// see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-elements-text-contents
})
});
it('.and() - chain multiple assertions together', () => {
// https://on.cypress.io/and
cy.get('.assertions-link')
.should('have.class', 'active')
.and('have.attr', 'href')
.and('include', 'cypress.io')
})
})
.and('include', 'cypress.io');
});
});
describe('Explicit Assertions', () => {
// https://on.cypress.io/assertions
it('expect - make an assertion about a specified subject', () => {
// We can use Chai's BDD style assertions
expect(true).to.be.true
const o = { foo: 'bar' }
expect(true).to.be.true;
const o = { foo: 'bar' };
expect(o).to.equal(o)
expect(o).to.deep.equal({ foo: 'bar' })
expect(o).to.equal(o);
expect(o).to.deep.equal({ foo: 'bar' });
// matching text using regular expression
expect('FooBar').to.match(/bar$/i)
})
expect('FooBar').to.match(/bar$/i);
});
it('pass your own callback function to should()', () => {
// Pass a function to should that can have any number
@ -71,14 +71,14 @@ context('Assertions', () => {
// https://on.cypress.io/$
// return an array of texts from all of the p's
// @ts-ignore TS6133 unused variable
const texts = $p.map((i, el) => Cypress.$(el).text())
const texts = $p.map((i, el) => Cypress.$(el).text());
// jquery map returns jquery object
// and .get() convert this to simple array
const paragraphs = texts.get()
const paragraphs = texts.get();
// array should have length of 3
expect(paragraphs, 'has 3 paragraphs').to.have.length(3)
expect(paragraphs, 'has 3 paragraphs').to.have.length(3);
// use second argument to expect(...) to provide clear
// message with each assertion
@ -86,27 +86,27 @@ context('Assertions', () => {
'Some text from first p',
'More text from second p',
'And even more text from third p',
])
})
})
]);
});
});
it('finds element by class name regex', () => {
cy.get('.docs-header')
.find('div')
// .should(cb) callback function will be retried
.should(($div) => {
expect($div).to.have.length(1)
expect($div).to.have.length(1);
const className = $div[0].className
const className = $div[0].className;
expect(className).to.match(/heading-/)
expect(className).to.match(/heading-/);
})
// .then(cb) callback is not retried,
// it either passes or fails
.then(($div) => {
expect($div, 'text content').to.have.text('Introduction')
})
})
expect($div, 'text content').to.have.text('Introduction');
});
});
it('can throw any error', () => {
cy.get('.docs-header')
@ -114,55 +114,56 @@ context('Assertions', () => {
.should(($div) => {
if ($div.length !== 1) {
// you can throw your own errors
throw new Error('Did not find 1 element')
throw new Error('Did not find 1 element');
}
const className = $div[0].className
const className = $div[0].className;
if (!className.match(/heading-/)) {
throw new Error(`Could not find class "heading-" in ${className}`)
throw new Error(`Could not find class "heading-" in ${className}`);
}
})
})
});
});
it('matches unknown text between two elements', () => {
/**
* Text from the first element.
*
* @type {string}
*/
let text
*/
let text;
/**
* Normalizes passed text,
* useful before comparing text with spaces and different capitalization.
* Normalizes passed text, useful before comparing text with spaces and different capitalization.
*
* @param {string} s Text to normalize
*/
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase()
*/
const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase();
cy.get('.two-elements')
.find('.first')
.then(($first) => {
// save text from the first element
text = normalizeText($first.text())
})
text = normalizeText($first.text());
});
cy.get('.two-elements')
.find('.second')
.should(($div) => {
// we can massage text before comparing
const secondText = normalizeText($div.text())
const secondText = normalizeText($div.text());
expect(secondText, 'second text').to.equal(text)
})
})
expect(secondText, 'second text').to.equal(text);
});
});
it('assert - assert shape of an object', () => {
const person = {
name: 'Joe',
age: 20,
}
};
assert.isObject(person, 'value is object')
})
})
})
assert.isObject(person, 'value is object');
});
});
});

View File

@ -2,55 +2,54 @@
context('Connectors', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/connectors')
})
cy.visit('https://example.cypress.io/commands/connectors');
});
it('.each() - iterate over an array of elements', () => {
// https://on.cypress.io/each
cy.get('.connectors-each-ul>li')
.each(($el, index, $list) => {
console.log($el, index, $list)
})
})
cy.get('.connectors-each-ul>li').each(($el, index, $list) => {
console.log($el, index, $list);
});
});
it('.its() - get properties on the current subject', () => {
// https://on.cypress.io/its
cy.get('.connectors-its-ul>li')
// calls the 'length' property yielding that value
.its('length')
.should('be.gt', 2)
})
.should('be.gt', 2);
});
it('.invoke() - invoke a function on the current subject', () => {
// our div is hidden in our script.js
// $('.connectors-div').hide()
// https://on.cypress.io/invoke
cy.get('.connectors-div').should('be.hidden')
cy.get('.connectors-div')
.should('be.hidden')
// call the jquery method 'show' on the 'div.container'
.invoke('show')
.should('be.visible')
})
.should('be.visible');
});
it('.spread() - spread an array as individual args to callback function', () => {
// https://on.cypress.io/spread
const arr = ['foo', 'bar', 'baz']
const arr = ['foo', 'bar', 'baz'];
cy.wrap(arr).spread((foo, bar, baz) => {
expect(foo).to.eq('foo')
expect(bar).to.eq('bar')
expect(baz).to.eq('baz')
})
})
expect(foo).to.eq('foo');
expect(bar).to.eq('bar');
expect(baz).to.eq('baz');
});
});
it('.then() - invoke a callback function with the current subject', () => {
// https://on.cypress.io/then
cy.get('.connectors-list > li')
.then(($lis) => {
expect($lis, '3 items').to.have.length(3)
expect($lis.eq(0), 'first item').to.contain('Walk the dog')
expect($lis.eq(1), 'second item').to.contain('Feed the cat')
expect($lis.eq(2), 'third item').to.contain('Write JavaScript')
})
})
})
cy.get('.connectors-list > li').then(($lis) => {
expect($lis, '3 items').to.have.length(3);
expect($lis.eq(0), 'first item').to.contain('Walk the dog');
expect($lis.eq(1), 'second item').to.contain('Feed the cat');
expect($lis.eq(2), 'third item').to.contain('Write JavaScript');
});
});
});

View File

@ -2,77 +2,78 @@
context('Cookies', () => {
beforeEach(() => {
Cypress.Cookies.debug(true)
Cypress.Cookies.debug(true);
cy.visit('https://example.cypress.io/commands/cookies')
cy.visit('https://example.cypress.io/commands/cookies');
// clear cookies again after visiting to remove
// any 3rd party cookies picked up such as cloudflare
cy.clearCookies()
})
cy.clearCookies();
});
it('cy.getCookie() - get a browser cookie', () => {
// https://on.cypress.io/getcookie
cy.get('#getCookie .set-a-cookie').click()
cy.get('#getCookie .set-a-cookie').click();
// cy.getCookie() yields a cookie object
cy.getCookie('token').should('have.property', 'value', '123ABC')
})
cy.getCookie('token').should('have.property', 'value', '123ABC');
});
it('cy.getCookies() - get browser cookies', () => {
// https://on.cypress.io/getcookies
cy.getCookies().should('be.empty')
cy.getCookies().should('be.empty');
cy.get('#getCookies .set-a-cookie').click()
cy.get('#getCookies .set-a-cookie').click();
// cy.getCookies() yields an array of cookies
cy.getCookies().should('have.length', 1).should((cookies) => {
// each cookie has these properties
expect(cookies[0]).to.have.property('name', 'token')
expect(cookies[0]).to.have.property('value', '123ABC')
expect(cookies[0]).to.have.property('httpOnly', false)
expect(cookies[0]).to.have.property('secure', false)
expect(cookies[0]).to.have.property('domain')
expect(cookies[0]).to.have.property('path')
})
})
cy.getCookies()
.should('have.length', 1)
.should((cookies) => {
// each cookie has these properties
expect(cookies[0]).to.have.property('name', 'token');
expect(cookies[0]).to.have.property('value', '123ABC');
expect(cookies[0]).to.have.property('httpOnly', false);
expect(cookies[0]).to.have.property('secure', false);
expect(cookies[0]).to.have.property('domain');
expect(cookies[0]).to.have.property('path');
});
});
it('cy.setCookie() - set a browser cookie', () => {
// https://on.cypress.io/setcookie
cy.getCookies().should('be.empty')
cy.getCookies().should('be.empty');
cy.setCookie('foo', 'bar')
cy.setCookie('foo', 'bar');
// cy.getCookie() yields a cookie object
cy.getCookie('foo').should('have.property', 'value', 'bar')
})
cy.getCookie('foo').should('have.property', 'value', 'bar');
});
it('cy.clearCookie() - clear a browser cookie', () => {
// https://on.cypress.io/clearcookie
cy.getCookie('token').should('be.null')
cy.getCookie('token').should('be.null');
cy.get('#clearCookie .set-a-cookie').click()
cy.get('#clearCookie .set-a-cookie').click();
cy.getCookie('token').should('have.property', 'value', '123ABC')
cy.getCookie('token').should('have.property', 'value', '123ABC');
// cy.clearCookies() yields null
cy.clearCookie('token').should('be.null')
cy.clearCookie('token').should('be.null');
cy.getCookie('token').should('be.null')
})
cy.getCookie('token').should('be.null');
});
it('cy.clearCookies() - clear browser cookies', () => {
// https://on.cypress.io/clearcookies
cy.getCookies().should('be.empty')
cy.getCookies().should('be.empty');
cy.get('#clearCookies .set-a-cookie').click()
cy.get('#clearCookies .set-a-cookie').click();
cy.getCookies().should('have.length', 1)
cy.getCookies().should('have.length', 1);
// cy.clearCookies() yields null
cy.clearCookies()
cy.clearCookies();
cy.getCookies().should('be.empty')
})
})
cy.getCookies().should('be.empty');
});
});

View File

@ -2,81 +2,85 @@
context('Cypress.Commands', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
// https://on.cypress.io/custom-commands
it('.add() - create a custom command', () => {
Cypress.Commands.add('console', {
prevSubject: true,
}, (subject, method) => {
// the previous subject is automatically received
// and the commands arguments are shifted
Cypress.Commands.add(
'console',
{
prevSubject: true,
},
(subject, method) => {
// the previous subject is automatically received
// and the commands arguments are shifted
// allow us to change the console method used
method = method || 'log'
// allow us to change the console method used
method = method || 'log';
// log the subject to the console
// @ts-ignore TS7017
console[method]('The subject is', subject)
// log the subject to the console
// @ts-ignore TS7017
console[method]('The subject is', subject);
// whatever we return becomes the new subject
// we don't want to change the subject so
// we return whatever was passed in
return subject
})
// whatever we return becomes the new subject
// we don't want to change the subject so
// we return whatever was passed in
return subject;
}
);
// @ts-ignore TS2339
cy.get('button').console('info').then(($button) => {
// subject is still $button
})
})
})
cy.get('button')
.console('info')
.then(($button) => {
// subject is still $button
});
});
});
context('Cypress.Cookies', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
// https://on.cypress.io/cookies
it('.debug() - enable or disable debugging', () => {
Cypress.Cookies.debug(true)
Cypress.Cookies.debug(true);
// Cypress will now log in the console when
// cookies are set or cleared
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
cy.clearCookie('fakeCookie')
cy.setCookie('fakeCookie', '123ABC')
})
cy.setCookie('fakeCookie', '123ABC');
cy.clearCookie('fakeCookie');
cy.setCookie('fakeCookie', '123ABC');
cy.clearCookie('fakeCookie');
cy.setCookie('fakeCookie', '123ABC');
});
it('.preserveOnce() - preserve cookies by key', () => {
// normally cookies are reset after each test
cy.getCookie('fakeCookie').should('not.be.ok')
cy.getCookie('fakeCookie').should('not.be.ok');
// preserving a cookie will not clear it when
// the next test starts
cy.setCookie('lastCookie', '789XYZ')
Cypress.Cookies.preserveOnce('lastCookie')
})
cy.setCookie('lastCookie', '789XYZ');
Cypress.Cookies.preserveOnce('lastCookie');
});
it('.defaults() - set defaults for all cookies', () => {
// now any cookie with the name 'session_id' will
// not be cleared before each new test runs
Cypress.Cookies.defaults({
whitelist: 'session_id',
})
})
})
});
});
});
context('Cypress.Server', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
// Permanently override server options for
// all instances of cy.server()
@ -86,71 +90,71 @@ context('Cypress.Server', () => {
Cypress.Server.defaults({
delay: 0,
force404: false,
})
})
})
});
});
});
context('Cypress.arch', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Get CPU architecture name of underlying OS', () => {
// https://on.cypress.io/arch
expect(Cypress.arch).to.exist
})
})
expect(Cypress.arch).to.exist;
});
});
context('Cypress.config()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Get and set configuration options', () => {
// https://on.cypress.io/config
let myConfig = Cypress.config()
let myConfig = Cypress.config();
expect(myConfig).to.have.property('animationDistanceThreshold', 5)
expect(myConfig).to.have.property('baseUrl', null)
expect(myConfig).to.have.property('defaultCommandTimeout', 4000)
expect(myConfig).to.have.property('requestTimeout', 5000)
expect(myConfig).to.have.property('responseTimeout', 30000)
expect(myConfig).to.have.property('viewportHeight', 660)
expect(myConfig).to.have.property('viewportWidth', 1000)
expect(myConfig).to.have.property('pageLoadTimeout', 60000)
expect(myConfig).to.have.property('waitForAnimations', true)
expect(myConfig).to.have.property('animationDistanceThreshold', 5);
expect(myConfig).to.have.property('baseUrl', null);
expect(myConfig).to.have.property('defaultCommandTimeout', 4000);
expect(myConfig).to.have.property('requestTimeout', 5000);
expect(myConfig).to.have.property('responseTimeout', 30000);
expect(myConfig).to.have.property('viewportHeight', 660);
expect(myConfig).to.have.property('viewportWidth', 1000);
expect(myConfig).to.have.property('pageLoadTimeout', 60000);
expect(myConfig).to.have.property('waitForAnimations', true);
expect(Cypress.config('pageLoadTimeout')).to.eq(60000)
expect(Cypress.config('pageLoadTimeout')).to.eq(60000);
// this will change the config for the rest of your tests!
Cypress.config('pageLoadTimeout', 20000)
Cypress.config('pageLoadTimeout', 20000);
expect(Cypress.config('pageLoadTimeout')).to.eq(20000)
expect(Cypress.config('pageLoadTimeout')).to.eq(20000);
Cypress.config('pageLoadTimeout', 60000)
})
})
Cypress.config('pageLoadTimeout', 60000);
});
});
context('Cypress.dom', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
// https://on.cypress.io/dom
it('.isHidden() - determine if a DOM element is hidden', () => {
let hiddenP = Cypress.$('.dom-p p.hidden').get(0)
let visibleP = Cypress.$('.dom-p p.visible').get(0)
let hiddenP = Cypress.$('.dom-p p.hidden').get(0);
let visibleP = Cypress.$('.dom-p p.visible').get(0);
// our first paragraph has css class 'hidden'
expect(Cypress.dom.isHidden(hiddenP)).to.be.true
expect(Cypress.dom.isHidden(visibleP)).to.be.false
})
})
expect(Cypress.dom.isHidden(hiddenP)).to.be.true;
expect(Cypress.dom.isHidden(visibleP)).to.be.false;
});
});
context('Cypress.env()', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
// We can set environment variables for highly dynamic values
@ -161,62 +165,61 @@ context('Cypress.env()', () => {
Cypress.env({
host: 'veronica.dev.local',
api_server: 'http://localhost:8888/v1/',
})
});
// get environment variable
expect(Cypress.env('host')).to.eq('veronica.dev.local')
expect(Cypress.env('host')).to.eq('veronica.dev.local');
// set environment variable
Cypress.env('api_server', 'http://localhost:8888/v2/')
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/')
Cypress.env('api_server', 'http://localhost:8888/v2/');
expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/');
// get all environment variable
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local')
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/')
})
})
expect(Cypress.env()).to.have.property('host', 'veronica.dev.local');
expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/');
});
});
context('Cypress.log', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Control what is printed to the Command Log', () => {
// https://on.cypress.io/cypress-log
})
})
});
});
context('Cypress.platform', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Get underlying OS name', () => {
// https://on.cypress.io/platform
expect(Cypress.platform).to.be.exist
})
})
expect(Cypress.platform).to.be.exist;
});
});
context('Cypress.version', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Get current version of Cypress being run', () => {
// https://on.cypress.io/version
expect(Cypress.version).to.be.exist
})
})
expect(Cypress.version).to.be.exist;
});
});
context('Cypress.spec', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/cypress-api')
})
cy.visit('https://example.cypress.io/cypress-api');
});
it('Get current spec information', () => {
// https://on.cypress.io/spec
// wrap the object so we can inspect it easily by clicking in the command log
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute'])
})
})
cy.wrap(Cypress.spec).should('have.keys', ['name', 'relative', 'absolute']);
});
});

View File

@ -3,18 +3,18 @@
/// JSON fixture file can be loaded directly using
// the built-in JavaScript bundler
// @ts-ignore
const requiredExample = require('../../fixtures/example')
const requiredExample = require('../../fixtures/example');
context('Files', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/files')
})
cy.visit('https://example.cypress.io/commands/files');
});
beforeEach(() => {
// load example.json fixture file and store
// in the test context object
cy.fixture('example.json').as('example')
})
cy.fixture('example.json').as('example');
});
it('cy.fixture() - load a fixture', () => {
// https://on.cypress.io/fixture
@ -22,57 +22,58 @@ context('Files', () => {
// Instead of writing a response inline you can
// use a fixture file's content.
cy.server()
cy.fixture('example.json').as('comment')
cy.server();
cy.fixture('example.json').as('comment');
// when application makes an Ajax request matching "GET comments/*"
// Cypress will intercept it and reply with object
// from the "comment" alias
cy.route('GET', 'comments/*', '@comment').as('getComment')
cy.route('GET', 'comments/*', '@comment').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.fixture-btn').click()
cy.get('.fixture-btn').click();
cy.wait('@getComment').its('responseBody')
cy.wait('@getComment')
.its('responseBody')
.should('have.property', 'name')
.and('include', 'Using fixtures to represent data')
.and('include', 'Using fixtures to represent data');
// you can also just write the fixture in the route
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment')
cy.route('GET', 'comments/*', 'fixture:example.json').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.fixture-btn').click()
cy.get('.fixture-btn').click();
cy.wait('@getComment').its('responseBody')
cy.wait('@getComment')
.its('responseBody')
.should('have.property', 'name')
.and('include', 'Using fixtures to represent data')
.and('include', 'Using fixtures to represent data');
// or write fx to represent fixture
// by default it assumes it's .json
cy.route('GET', 'comments/*', 'fx:example').as('getComment')
cy.route('GET', 'comments/*', 'fx:example').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.fixture-btn').click()
cy.get('.fixture-btn').click();
cy.wait('@getComment').its('responseBody')
cy.wait('@getComment')
.its('responseBody')
.should('have.property', 'name')
.and('include', 'Using fixtures to represent data')
})
.and('include', 'Using fixtures to represent data');
});
it('cy.fixture() or require - load a fixture', function () {
// we are inside the "function () { ... }"
// callback and can use test context object "this"
// "this.example" was loaded in "beforeEach" function callback
expect(this.example, 'fixture in the test context')
.to.deep.equal(requiredExample)
expect(this.example, 'fixture in the test context').to.deep.equal(requiredExample);
// or use "cy.wrap" and "should('deep.equal', ...)" assertion
// @ts-ignore
cy.wrap(this.example, 'fixture vs require')
.should('deep.equal', requiredExample)
})
cy.wrap(this.example, 'fixture vs require').should('deep.equal', requiredExample);
});
it('cy.readFile() - read a files contents', () => {
// https://on.cypress.io/readfile
@ -80,9 +81,9 @@ context('Files', () => {
// You can read a file and yield its contents
// The filePath is relative to your project's root.
cy.readFile('cypress.json').then((json) => {
expect(json).to.be.an('object')
})
})
expect(json).to.be.an('object');
});
});
it('cy.writeFile() - write to a file', () => {
// https://on.cypress.io/writefile
@ -91,13 +92,12 @@ context('Files', () => {
// Use a response from a request to automatically
// generate a fixture file for use later
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body)
})
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
cy.writeFile('cypress/fixtures/users.json', response.body);
});
cy.fixture('users').should((users) => {
expect(users[0].name).to.exist
})
expect(users[0].name).to.exist;
});
// JavaScript arrays and objects are stringified
// and formatted into text.
@ -105,10 +105,10 @@ context('Files', () => {
id: 8739,
name: 'Jane',
email: 'jane@example.com',
})
});
cy.fixture('profile').should((profile) => {
expect(profile.name).to.eq('Jane')
})
})
})
expect(profile.name).to.eq('Jane');
});
});
});

View File

@ -2,51 +2,57 @@
context('Local Storage', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/local-storage')
})
cy.visit('https://example.cypress.io/commands/local-storage');
});
// Although local storage is automatically cleared
// in between tests to maintain a clean state
// sometimes we need to clear the local storage manually
it('cy.clearLocalStorage() - clear all data in local storage', () => {
// https://on.cypress.io/clearlocalstorage
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
cy.get('.ls-btn')
.click()
.should(() => {
expect(localStorage.getItem('prop1')).to.eq('red');
expect(localStorage.getItem('prop2')).to.eq('blue');
expect(localStorage.getItem('prop3')).to.eq('magenta');
});
// clearLocalStorage() yields the localStorage object
cy.clearLocalStorage().should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.be.null
})
expect(ls.getItem('prop1')).to.be.null;
expect(ls.getItem('prop2')).to.be.null;
expect(ls.getItem('prop3')).to.be.null;
});
// Clear key matching string in Local Storage
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
cy.get('.ls-btn')
.click()
.should(() => {
expect(localStorage.getItem('prop1')).to.eq('red');
expect(localStorage.getItem('prop2')).to.eq('blue');
expect(localStorage.getItem('prop3')).to.eq('magenta');
});
cy.clearLocalStorage('prop1').should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.eq('blue')
expect(ls.getItem('prop3')).to.eq('magenta')
})
expect(ls.getItem('prop1')).to.be.null;
expect(ls.getItem('prop2')).to.eq('blue');
expect(ls.getItem('prop3')).to.eq('magenta');
});
// Clear keys matching regex in Local Storage
cy.get('.ls-btn').click().should(() => {
expect(localStorage.getItem('prop1')).to.eq('red')
expect(localStorage.getItem('prop2')).to.eq('blue')
expect(localStorage.getItem('prop3')).to.eq('magenta')
})
cy.get('.ls-btn')
.click()
.should(() => {
expect(localStorage.getItem('prop1')).to.eq('red');
expect(localStorage.getItem('prop2')).to.eq('blue');
expect(localStorage.getItem('prop3')).to.eq('magenta');
});
cy.clearLocalStorage(/prop1|2/).should((ls) => {
expect(ls.getItem('prop1')).to.be.null
expect(ls.getItem('prop2')).to.be.null
expect(ls.getItem('prop3')).to.eq('magenta')
})
})
})
expect(ls.getItem('prop1')).to.be.null;
expect(ls.getItem('prop2')).to.be.null;
expect(ls.getItem('prop3')).to.eq('magenta');
});
});
});

View File

@ -2,31 +2,31 @@
context('Location', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/location')
})
cy.visit('https://example.cypress.io/commands/location');
});
it('cy.hash() - get the current URL hash', () => {
// https://on.cypress.io/hash
cy.hash().should('be.empty')
})
cy.hash().should('be.empty');
});
it('cy.location() - get window.location', () => {
// https://on.cypress.io/location
cy.location().should((location) => {
expect(location.hash).to.be.empty
expect(location.href).to.eq('https://example.cypress.io/commands/location')
expect(location.host).to.eq('example.cypress.io')
expect(location.hostname).to.eq('example.cypress.io')
expect(location.origin).to.eq('https://example.cypress.io')
expect(location.pathname).to.eq('/commands/location')
expect(location.port).to.eq('')
expect(location.protocol).to.eq('https:')
expect(location.search).to.be.empty
})
})
expect(location.hash).to.be.empty;
expect(location.href).to.eq('https://example.cypress.io/commands/location');
expect(location.host).to.eq('example.cypress.io');
expect(location.hostname).to.eq('example.cypress.io');
expect(location.origin).to.eq('https://example.cypress.io');
expect(location.pathname).to.eq('/commands/location');
expect(location.port).to.eq('');
expect(location.protocol).to.eq('https:');
expect(location.search).to.be.empty;
});
});
it('cy.url() - get the current URL', () => {
// https://on.cypress.io/url
cy.url().should('eq', 'https://example.cypress.io/commands/location')
})
})
cy.url().should('eq', 'https://example.cypress.io/commands/location');
});
});

View File

@ -2,8 +2,8 @@
context('Misc', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/misc')
})
cy.visit('https://example.cypress.io/commands/misc');
});
it('.end() - end the command chain', () => {
// https://on.cypress.io/end
@ -12,12 +12,12 @@ context('Misc', () => {
// and force Cypress to re-query from the root element
cy.get('.misc-table').within(() => {
// ends the current chain and yields null
cy.contains('Cheryl').click().end()
cy.contains('Cheryl').click().end();
// queries the entire table again
cy.contains('Charles').click()
})
})
cy.contains('Charles').click();
});
});
it('cy.exec() - execute a system command', () => {
// https://on.cypress.io/exec
@ -25,40 +25,36 @@ context('Misc', () => {
// execute a system command.
// so you can take actions necessary for
// your test outside the scope of Cypress.
cy.exec('echo Jane Lane')
.its('stdout').should('contain', 'Jane Lane')
cy.exec('echo Jane Lane').its('stdout').should('contain', 'Jane Lane');
// we can use Cypress.platform string to
// select appropriate command
// https://on.cypress/io/platform
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`)
cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`);
if (Cypress.platform === 'win32') {
cy.exec('print cypress.json')
.its('stderr').should('be.empty')
cy.exec('print cypress.json').its('stderr').should('be.empty');
} else {
cy.exec('cat cypress.json')
.its('stderr').should('be.empty')
cy.exec('cat cypress.json').its('stderr').should('be.empty');
cy.exec('pwd')
.its('code').should('eq', 0)
cy.exec('pwd').its('code').should('eq', 0);
}
})
});
it('cy.focused() - get the DOM element that has focus', () => {
// https://on.cypress.io/focused
cy.get('.misc-form').find('#name').click()
cy.focused().should('have.id', 'name')
cy.get('.misc-form').find('#name').click();
cy.focused().should('have.id', 'name');
cy.get('.misc-form').find('#description').click()
cy.focused().should('have.id', 'description')
})
cy.get('.misc-form').find('#description').click();
cy.focused().should('have.id', 'description');
});
context('Cypress.Screenshot', function () {
it('cy.screenshot() - take a screenshot', () => {
// https://on.cypress.io/screenshot
cy.screenshot('my-image')
})
cy.screenshot('my-image');
});
it('Cypress.Screenshot.defaults() - change default config of screenshots', function () {
Cypress.Screenshot.defaults({
@ -68,16 +64,14 @@ context('Misc', () => {
scale: false,
disableTimersAndAnimations: true,
screenshotOnRunFailure: true,
beforeScreenshot () { },
afterScreenshot () { },
})
})
})
beforeScreenshot() {},
afterScreenshot() {},
});
});
});
it('cy.wrap() - wrap an object', () => {
// https://on.cypress.io/wrap
cy.wrap({ foo: 'bar' })
.should('have.property', 'foo')
.and('include', 'bar')
})
})
cy.wrap({ foo: 'bar' }).should('have.property', 'foo').and('include', 'bar');
});
});

View File

@ -2,38 +2,38 @@
context('Navigation', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io')
cy.get('.navbar-nav').contains('Commands').click()
cy.get('.dropdown-menu').contains('Navigation').click()
})
cy.visit('https://example.cypress.io');
cy.get('.navbar-nav').contains('Commands').click();
cy.get('.dropdown-menu').contains('Navigation').click();
});
it('cy.go() - go back or forward in the browser\'s history', () => {
it("cy.go() - go back or forward in the browser's history", () => {
// https://on.cypress.io/go
cy.location('pathname').should('include', 'navigation')
cy.location('pathname').should('include', 'navigation');
cy.go('back')
cy.location('pathname').should('not.include', 'navigation')
cy.go('back');
cy.location('pathname').should('not.include', 'navigation');
cy.go('forward')
cy.location('pathname').should('include', 'navigation')
cy.go('forward');
cy.location('pathname').should('include', 'navigation');
// clicking back
cy.go(-1)
cy.location('pathname').should('not.include', 'navigation')
cy.go(-1);
cy.location('pathname').should('not.include', 'navigation');
// clicking forward
cy.go(1)
cy.location('pathname').should('include', 'navigation')
})
cy.go(1);
cy.location('pathname').should('include', 'navigation');
});
it('cy.reload() - reload the page', () => {
// https://on.cypress.io/reload
cy.reload()
cy.reload();
// reload the page without using the cache
cy.reload(true)
})
cy.reload(true);
});
it('cy.visit() - visit a remote url', () => {
// https://on.cypress.io/visit
@ -43,14 +43,14 @@ context('Navigation', () => {
// Pass options to the visit
cy.visit('https://example.cypress.io/commands/navigation', {
timeout: 50000, // increase total time for the visit to resolve
onBeforeLoad (contentWindow) {
onBeforeLoad(contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
expect(typeof contentWindow === 'object').to.be.true;
},
onLoad (contentWindow) {
onLoad(contentWindow) {
// contentWindow is the remote page's window object
expect(typeof contentWindow === 'object').to.be.true
expect(typeof contentWindow === 'object').to.be.true;
},
})
})
})
});
});
});

View File

@ -2,8 +2,8 @@
context('Network Requests', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/network-requests')
})
cy.visit('https://example.cypress.io/commands/network-requests');
});
// Manage AJAX / XHR requests in your app
@ -13,59 +13,56 @@ context('Network Requests', () => {
cy.server().should((server) => {
// the default options on server
// you can override any of these options
expect(server.delay).to.eq(0)
expect(server.method).to.eq('GET')
expect(server.status).to.eq(200)
expect(server.headers).to.be.null
expect(server.response).to.be.null
expect(server.onRequest).to.be.undefined
expect(server.onResponse).to.be.undefined
expect(server.onAbort).to.be.undefined
expect(server.delay).to.eq(0);
expect(server.method).to.eq('GET');
expect(server.status).to.eq(200);
expect(server.headers).to.be.null;
expect(server.response).to.be.null;
expect(server.onRequest).to.be.undefined;
expect(server.onResponse).to.be.undefined;
expect(server.onAbort).to.be.undefined;
// These options control the server behavior
// affecting all requests
// pass false to disable existing route stubs
expect(server.enable).to.be.true
expect(server.enable).to.be.true;
// forces requests that don't match your routes to 404
expect(server.force404).to.be.false
expect(server.force404).to.be.false;
// whitelists requests from ever being logged or stubbed
expect(server.whitelist).to.be.a('function')
})
expect(server.whitelist).to.be.a('function');
});
cy.server({
method: 'POST',
delay: 1000,
status: 422,
response: {},
})
});
// any route commands will now inherit the above options
// from the server. anything we pass specifically
// to route will override the defaults though.
})
});
it('cy.request() - make an XHR request', () => {
// https://on.cypress.io/request
cy.request('https://jsonplaceholder.cypress.io/comments')
.should((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.have.length(500)
expect(response).to.have.property('headers')
expect(response).to.have.property('duration')
})
})
cy.request('https://jsonplaceholder.cypress.io/comments').should((response) => {
expect(response.status).to.eq(200);
expect(response.body).to.have.length(500);
expect(response).to.have.property('headers');
expect(response).to.have.property('duration');
});
});
it('cy.request() - verify response using BDD syntax', () => {
cy.request('https://jsonplaceholder.cypress.io/comments')
.then((response) => {
cy.request('https://jsonplaceholder.cypress.io/comments').then((response) => {
// https://on.cypress.io/assertions
expect(response).property('status').to.equal(200)
expect(response).property('body').to.have.length(500)
expect(response).to.include.keys('headers', 'duration')
})
})
expect(response).property('status').to.equal(200);
expect(response).property('body').to.have.length(500);
expect(response).to.include.keys('headers', 'duration');
});
});
it('cy.request() with query parameters', () => {
// will execute request
@ -77,42 +74,42 @@ context('Network Requests', () => {
id: 3,
},
})
.its('body')
.should('be.an', 'array')
.and('have.length', 1)
.its('0') // yields first element of the array
.should('contain', {
postId: 1,
id: 3,
})
})
.its('body')
.should('be.an', 'array')
.and('have.length', 1)
.its('0') // yields first element of the array
.should('contain', {
postId: 1,
id: 3,
});
});
it('cy.request() - pass result to the second request', () => {
// first, let's find out the userId of the first user we have
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
.its('body.0') // yields the first element of the returned list
.then((user) => {
expect(user).property('id').to.be.a('number')
expect(user).property('id').to.be.a('number');
// make a new post on behalf of the user
cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
userId: user.id,
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
});
})
// note that the value here is the returned value of the 2nd request
// which is the new post object
.then((response) => {
expect(response).property('status').to.equal(201) // new entity created
expect(response).property('status').to.equal(201); // new entity created
expect(response).property('body').to.contain({
id: 101, // there are already 100 posts, so new entity gets id 101
title: 'Cypress Test Runner',
})
});
// we don't know the user id here - since it was in above closure
// so in this test just confirm that the property is there
expect(response.body).property('userId').to.be.a('number')
})
})
expect(response.body).property('userId').to.be.a('number');
});
});
it('cy.request() - save response in the shared test context', () => {
// https://on.cypress.io/variables-and-aliases
@ -131,47 +128,48 @@ context('Network Requests', () => {
title: 'Cypress Test Runner',
body: 'Fast, easy and reliable testing for anything that runs in a browser.',
})
.its('body').as('post') // save the new post from the response
.its('body')
.as('post'); // save the new post from the response
})
.then(function () {
// When this callback runs, both "cy.request" API commands have finished
// and the test context has "user" and "post" objects set.
// Let's verify them.
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
})
})
expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id);
});
});
it('cy.route() - route responses to matching requests', () => {
// https://on.cypress.io/route
let message = 'whoa, this comment does not exist'
let message = 'whoa, this comment does not exist';
cy.server()
cy.server();
// Listen to GET to comments/1
cy.route('GET', 'comments/*').as('getComment')
cy.route('GET', 'comments/*').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
cy.get('.network-btn').click();
// https://on.cypress.io/wait
cy.wait('@getComment').its('status').should('eq', 200)
cy.wait('@getComment').its('status').should('eq', 200);
// Listen to POST to comments
cy.route('POST', '/comments').as('postComment')
cy.route('POST', '/comments').as('postComment');
// we have code that posts a comment when
// the button is clicked in scripts.js
cy.get('.network-post').click()
cy.wait('@postComment')
cy.get('.network-post').click();
cy.wait('@postComment');
// get the route
cy.get('@postComment').should((xhr) => {
expect(xhr.requestBody).to.include('email')
expect(xhr.requestHeaders).to.have.property('Content-Type')
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()')
})
expect(xhr.requestBody).to.include('email');
expect(xhr.requestHeaders).to.have.property('Content-Type');
expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()');
});
// Stub a response to PUT comments/ ****
cy.route({
@ -180,15 +178,15 @@ context('Network Requests', () => {
status: 404,
response: { error: message },
delay: 500,
}).as('putComment')
}).as('putComment');
// we have code that puts a comment when
// the button is clicked in scripts.js
cy.get('.network-put').click()
cy.get('.network-put').click();
cy.wait('@putComment')
cy.wait('@putComment');
// our 404 statusCode logic in scripts.js executed
cy.get('.network-put-comment').should('contain', message)
})
})
cy.get('.network-put-comment').should('contain', message);
});
});

View File

@ -2,8 +2,8 @@
context('Querying', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/querying')
})
cy.visit('https://example.cypress.io/commands/querying');
});
// The most commonly used query is 'cy.get()', you can
// think of this like the '$' in jQuery
@ -11,77 +11,65 @@ context('Querying', () => {
it('cy.get() - query DOM elements', () => {
// https://on.cypress.io/get
cy.get('#query-btn').should('contain', 'Button')
cy.get('#query-btn').should('contain', 'Button');
cy.get('.query-btn').should('contain', 'Button')
cy.get('.query-btn').should('contain', 'Button');
cy.get('#querying .well>button:first').should('contain', 'Button')
cy.get('#querying .well>button:first').should('contain', 'Button');
// ↲
// Use CSS selectors just like jQuery
cy.get('[data-test-id="test-example"]').should('have.class', 'example')
cy.get('[data-test-id="test-example"]').should('have.class', 'example');
// 'cy.get()' yields jQuery object, you can get its attribute
// by invoking `.attr()` method
cy.get('[data-test-id="test-example"]')
.invoke('attr', 'data-test-id')
.should('equal', 'test-example')
.should('equal', 'test-example');
// or you can get element's CSS property
cy.get('[data-test-id="test-example"]')
.invoke('css', 'position')
.should('equal', 'static')
cy.get('[data-test-id="test-example"]').invoke('css', 'position').should('equal', 'static');
// or use assertions directly during 'cy.get()'
// https://on.cypress.io/assertions
cy.get('[data-test-id="test-example"]')
.should('have.attr', 'data-test-id', 'test-example')
.and('have.css', 'position', 'static')
})
.and('have.css', 'position', 'static');
});
it('cy.contains() - query DOM elements with matching content', () => {
// https://on.cypress.io/contains
cy.get('.query-list')
.contains('bananas')
.should('have.class', 'third')
cy.get('.query-list').contains('bananas').should('have.class', 'third');
// we can pass a regexp to `.contains()`
cy.get('.query-list')
.contains(/^b\w+/)
.should('have.class', 'third')
cy.get('.query-list').contains(/^b\w+/).should('have.class', 'third');
cy.get('.query-list')
.contains('apples')
.should('have.class', 'first')
cy.get('.query-list').contains('apples').should('have.class', 'first');
// passing a selector to contains will
// yield the selector containing the text
cy.get('#querying')
.contains('ul', 'oranges')
.should('have.class', 'query-list')
cy.get('#querying').contains('ul', 'oranges').should('have.class', 'query-list');
cy.get('.query-button')
.contains('Save Form')
.should('have.class', 'btn')
})
cy.get('.query-button').contains('Save Form').should('have.class', 'btn');
});
it('.within() - query DOM elements within a specific element', () => {
// https://on.cypress.io/within
cy.get('.query-form').within(() => {
cy.get('input:first').should('have.attr', 'placeholder', 'Email')
cy.get('input:last').should('have.attr', 'placeholder', 'Password')
})
})
cy.get('input:first').should('have.attr', 'placeholder', 'Email');
cy.get('input:last').should('have.attr', 'placeholder', 'Password');
});
});
it('cy.root() - query the root DOM element', () => {
// https://on.cypress.io/root
// By default, root is the document
cy.root().should('match', 'html')
cy.root().should('match', 'html');
cy.get('.query-ul').within(() => {
// In this within, the root is now the ul DOM element
cy.root().should('have.class', 'query-ul')
})
})
})
cy.root().should('have.class', 'query-ul');
});
});
});

View File

@ -3,93 +3,92 @@
context('Spies, Stubs, and Clock', () => {
it('cy.spy() - wrap a method in a spy', () => {
// https://on.cypress.io/spy
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
const obj = {
foo () {},
}
foo() {},
};
const spy = cy.spy(obj, 'foo').as('anyArgs')
const spy = cy.spy(obj, 'foo').as('anyArgs');
obj.foo()
obj.foo();
expect(spy).to.be.called
})
expect(spy).to.be.called;
});
it('cy.spy() retries until assertions pass', () => {
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
const obj = {
/**
* Prints the argument passed
*
* @param x {any}
*/
foo (x) {
console.log('obj.foo called with', x)
*/
foo(x) {
console.log('obj.foo called with', x);
},
}
};
cy.spy(obj, 'foo').as('foo')
cy.spy(obj, 'foo').as('foo');
setTimeout(() => {
obj.foo('first')
}, 500)
obj.foo('first');
}, 500);
setTimeout(() => {
obj.foo('second')
}, 2500)
obj.foo('second');
}, 2500);
cy.get('@foo').should('have.been.calledTwice')
})
cy.get('@foo').should('have.been.calledTwice');
});
it('cy.stub() - create a stub and/or replace a function with stub', () => {
// https://on.cypress.io/stub
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
const obj = {
/**
* prints both arguments to the console
* Prints both arguments to the console
*
* @param a {string}
* @param b {string}
*/
foo (a, b) {
console.log('a', a, 'b', b)
*/
foo(a, b) {
console.log('a', a, 'b', b);
},
}
};
const stub = cy.stub(obj, 'foo').as('foo')
const stub = cy.stub(obj, 'foo').as('foo');
obj.foo('foo', 'bar')
obj.foo('foo', 'bar');
expect(stub).to.be.called
})
expect(stub).to.be.called;
});
it('cy.clock() - control time in the browser', () => {
// https://on.cypress.io/clock
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#clock-div').click()
.should('have.text', '1489449600')
})
cy.clock(now);
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
cy.get('#clock-div').click().should('have.text', '1489449600');
});
it('cy.tick() - move time in the browser', () => {
// https://on.cypress.io/tick
// create the date in UTC so its always the same
// no matter what local timezone the browser is running in
const now = new Date(Date.UTC(2017, 2, 14)).getTime()
const now = new Date(Date.UTC(2017, 2, 14)).getTime();
cy.clock(now)
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks')
cy.get('#tick-div').click()
.should('have.text', '1489449600')
cy.tick(10000) // 10 seconds passed
cy.get('#tick-div').click()
.should('have.text', '1489449610')
})
})
cy.clock(now);
cy.visit('https://example.cypress.io/commands/spies-stubs-clocks');
cy.get('#tick-div').click().should('have.text', '1489449600');
cy.tick(10000); // 10 seconds passed
cy.get('#tick-div').click().should('have.text', '1489449610');
});
});

View File

@ -2,120 +2,96 @@
context('Traversal', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/traversal')
})
cy.visit('https://example.cypress.io/commands/traversal');
});
it('.children() - get child DOM elements', () => {
// https://on.cypress.io/children
cy.get('.traversal-breadcrumb')
.children('.active')
.should('contain', 'Data')
})
cy.get('.traversal-breadcrumb').children('.active').should('contain', 'Data');
});
it('.closest() - get closest ancestor DOM element', () => {
// https://on.cypress.io/closest
cy.get('.traversal-badge')
.closest('ul')
.should('have.class', 'list-group')
})
cy.get('.traversal-badge').closest('ul').should('have.class', 'list-group');
});
it('.eq() - get a DOM element at a specific index', () => {
// https://on.cypress.io/eq
cy.get('.traversal-list>li')
.eq(1).should('contain', 'siamese')
})
cy.get('.traversal-list>li').eq(1).should('contain', 'siamese');
});
it('.filter() - get DOM elements that match the selector', () => {
// https://on.cypress.io/filter
cy.get('.traversal-nav>li')
.filter('.active').should('contain', 'About')
})
cy.get('.traversal-nav>li').filter('.active').should('contain', 'About');
});
it('.find() - get descendant DOM elements of the selector', () => {
// https://on.cypress.io/find
cy.get('.traversal-pagination')
.find('li').find('a')
.should('have.length', 7)
})
cy.get('.traversal-pagination').find('li').find('a').should('have.length', 7);
});
it('.first() - get first DOM element', () => {
// https://on.cypress.io/first
cy.get('.traversal-table td')
.first().should('contain', '1')
})
cy.get('.traversal-table td').first().should('contain', '1');
});
it('.last() - get last DOM element', () => {
// https://on.cypress.io/last
cy.get('.traversal-buttons .btn')
.last().should('contain', 'Submit')
})
cy.get('.traversal-buttons .btn').last().should('contain', 'Submit');
});
it('.next() - get next sibling DOM element', () => {
// https://on.cypress.io/next
cy.get('.traversal-ul')
.contains('apples').next().should('contain', 'oranges')
})
cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges');
});
it('.nextAll() - get all next sibling DOM elements', () => {
// https://on.cypress.io/nextall
cy.get('.traversal-next-all')
.contains('oranges')
.nextAll().should('have.length', 3)
})
cy.get('.traversal-next-all').contains('oranges').nextAll().should('have.length', 3);
});
it('.nextUntil() - get next sibling DOM elements until next el', () => {
// https://on.cypress.io/nextuntil
cy.get('#veggies')
.nextUntil('#nuts').should('have.length', 3)
})
cy.get('#veggies').nextUntil('#nuts').should('have.length', 3);
});
it('.not() - remove DOM elements from set of DOM elements', () => {
// https://on.cypress.io/not
cy.get('.traversal-disabled .btn')
.not('[disabled]').should('not.contain', 'Disabled')
})
cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled');
});
it('.parent() - get parent DOM element from DOM elements', () => {
// https://on.cypress.io/parent
cy.get('.traversal-mark')
.parent().should('contain', 'Morbi leo risus')
})
cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus');
});
it('.parents() - get parent DOM elements from DOM elements', () => {
// https://on.cypress.io/parents
cy.get('.traversal-cite')
.parents().should('match', 'blockquote')
})
cy.get('.traversal-cite').parents().should('match', 'blockquote');
});
it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => {
// https://on.cypress.io/parentsuntil
cy.get('.clothes-nav')
.find('.active')
.parentsUntil('.clothes-nav')
.should('have.length', 2)
})
cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav').should('have.length', 2);
});
it('.prev() - get previous sibling DOM element', () => {
// https://on.cypress.io/prev
cy.get('.birds').find('.active')
.prev().should('contain', 'Lorikeets')
})
cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets');
});
it('.prevAll() - get all previous sibling DOM elements', () => {
// https://on.cypress.io/prevAll
cy.get('.fruits-list').find('.third')
.prevAll().should('have.length', 2)
})
cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2);
});
it('.prevUntil() - get all previous sibling DOM elements until el', () => {
// https://on.cypress.io/prevUntil
cy.get('.foods-list').find('#nuts')
.prevUntil('#veggies').should('have.length', 3)
})
cy.get('.foods-list').find('#nuts').prevUntil('#veggies').should('have.length', 3);
});
it('.siblings() - get all sibling DOM elements', () => {
// https://on.cypress.io/siblings
cy.get('.traversal-pills .active')
.siblings().should('have.length', 2)
})
})
cy.get('.traversal-pills .active').siblings().should('have.length', 2);
});
});

View File

@ -2,132 +2,128 @@
context('Utilities', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/utilities')
})
cy.visit('https://example.cypress.io/utilities');
});
it('Cypress._ - call a lodash method', () => {
// https://on.cypress.io/_
cy.request('https://jsonplaceholder.cypress.io/users')
.then((response) => {
let ids = Cypress._.chain(response.body).map('id').take(3).value()
cy.request('https://jsonplaceholder.cypress.io/users').then((response) => {
let ids = Cypress._.chain(response.body).map('id').take(3).value();
expect(ids).to.deep.eq([1, 2, 3])
})
})
expect(ids).to.deep.eq([1, 2, 3]);
});
});
it('Cypress.$ - call a jQuery method', () => {
// https://on.cypress.io/$
let $li = Cypress.$('.utility-jquery li:first')
let $li = Cypress.$('.utility-jquery li:first');
cy.wrap($li)
.should('not.have.class', 'active')
.click()
.should('have.class', 'active')
})
cy.wrap($li).should('not.have.class', 'active').click().should('have.class', 'active');
});
it('Cypress.Blob - blob utilities and base64 string conversion', () => {
// https://on.cypress.io/blob
cy.get('.utility-blob').then(($div) =>
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
// get the dataUrl string for the javascript-logo
Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous')
.then((dataUrl) => {
// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
// get the dataUrl string for the javascript-logo
Cypress.Blob.imgSrcToDataURL(
'https://example.cypress.io/assets/img/javascript-logo.png',
undefined,
'anonymous'
).then((dataUrl) => {
// create an <img> element and set its src to the dataUrl
let img = Cypress.$('<img />', { src: dataUrl })
let img = Cypress.$('<img />', { src: dataUrl });
// need to explicitly return cy here since we are initially returning
// the Cypress.Blob.imgSrcToDataURL promise to our test
// append the image
$div.append(img)
$div.append(img);
cy.get('.utility-blob img').click()
.should('have.attr', 'src', dataUrl)
}))
})
cy.get('.utility-blob img').click().should('have.attr', 'src', dataUrl);
})
);
});
it('Cypress.minimatch - test out glob patterns against strings', () => {
// https://on.cypress.io/minimatch
let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', {
matchBase: true,
})
});
expect(matching, 'matching wildcard').to.be.true
expect(matching, 'matching wildcard').to.be.true;
matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', {
matchBase: true,
})
expect(matching, 'comments').to.be.false
});
expect(matching, 'comments').to.be.false;
// ** matches against all downstream path segments
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', {
matchBase: true,
})
expect(matching, 'comments').to.be.true
});
expect(matching, 'comments').to.be.true;
// whereas * matches only the next path segment
matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', {
matchBase: false,
})
expect(matching, 'comments').to.be.false
})
});
expect(matching, 'comments').to.be.false;
});
it('Cypress.moment() - format or parse dates using a moment method', () => {
// https://on.cypress.io/moment
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A')
const time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A');
expect(time).to.be.a('string')
expect(time).to.be.a('string');
cy.get('.utility-moment').contains('3:38 PM')
.should('have.class', 'badge')
cy.get('.utility-moment').contains('3:38 PM').should('have.class', 'badge');
// the time in the element should be between 3pm and 5pm
const start = Cypress.moment('3:00 PM', 'LT')
const end = Cypress.moment('5:00 PM', 'LT')
const start = Cypress.moment('3:00 PM', 'LT');
const end = Cypress.moment('5:00 PM', 'LT');
cy.get('.utility-moment .badge')
.should(($el) => {
// parse American time like "3:38 PM"
const m = Cypress.moment($el.text().trim(), 'LT')
cy.get('.utility-moment .badge').should(($el) => {
// parse American time like "3:38 PM"
const m = Cypress.moment($el.text().trim(), 'LT');
// display hours + minutes + AM|PM
const f = 'h:mm A'
expect(m.isBetween(start, end),
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`).to.be.true
})
})
// display hours + minutes + AM|PM
const f = 'h:mm A';
expect(
m.isBetween(start, end),
`${m.format(f)} should be between ${start.format(f)} and ${end.format(f)}`
).to.be.true;
});
});
it('Cypress.Promise - instantiate a bluebird promise', () => {
// https://on.cypress.io/promise
let waited = false
let waited = false;
/**
* @return Bluebird<string>
*/
function waitOneSecond () {
/** @returns Bluebird<string> */
function waitOneSecond() {
// return a promise that resolves after 1 second
// @ts-ignore TS2351 (new Cypress.Promise)
return new Cypress.Promise((resolve, reject) => {
setTimeout(() => {
// set waited to true
waited = true
waited = true;
// resolve with 'foo' string
resolve('foo')
}, 1000)
})
resolve('foo');
}, 1000);
});
}
cy.then(() =>
// return a promise to cy.then() that
// is awaited until it resolves
// return a promise to cy.then() that
// is awaited until it resolves
// @ts-ignore TS7006
waitOneSecond().then((str) => {
expect(str).to.eq('foo')
expect(waited).to.be.true
}))
})
})
expect(str).to.eq('foo');
expect(waited).to.be.true;
})
);
});
});

View File

@ -2,22 +2,22 @@
context('Viewport', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/viewport')
})
cy.visit('https://example.cypress.io/commands/viewport');
});
it('cy.viewport() - set the viewport size and dimension', () => {
// https://on.cypress.io/viewport
cy.get('#navbar').should('be.visible')
cy.viewport(320, 480)
cy.get('#navbar').should('be.visible');
cy.viewport(320, 480);
// the navbar should have collapse since our screen is smaller
cy.get('#navbar').should('not.be.visible')
cy.get('.navbar-toggle').should('be.visible').click()
cy.get('.nav').find('a').should('be.visible')
cy.get('#navbar').should('not.be.visible');
cy.get('.navbar-toggle').should('be.visible').click();
cy.get('.nav').find('a').should('be.visible');
// lets see what our app looks like on a super large screen
cy.viewport(2999, 2999)
cy.viewport(2999, 2999);
// cy.viewport() accepts a set of preset sizes
// to easily set the screen to a device's width and height
@ -25,35 +25,35 @@ context('Viewport', () => {
// We added a cy.wait() between each viewport change so you can see
// the change otherwise it is a little too fast to see :)
cy.viewport('macbook-15')
cy.wait(200)
cy.viewport('macbook-13')
cy.wait(200)
cy.viewport('macbook-11')
cy.wait(200)
cy.viewport('ipad-2')
cy.wait(200)
cy.viewport('ipad-mini')
cy.wait(200)
cy.viewport('iphone-6+')
cy.wait(200)
cy.viewport('iphone-6')
cy.wait(200)
cy.viewport('iphone-5')
cy.wait(200)
cy.viewport('iphone-4')
cy.wait(200)
cy.viewport('iphone-3')
cy.wait(200)
cy.viewport('macbook-15');
cy.wait(200);
cy.viewport('macbook-13');
cy.wait(200);
cy.viewport('macbook-11');
cy.wait(200);
cy.viewport('ipad-2');
cy.wait(200);
cy.viewport('ipad-mini');
cy.wait(200);
cy.viewport('iphone-6+');
cy.wait(200);
cy.viewport('iphone-6');
cy.wait(200);
cy.viewport('iphone-5');
cy.wait(200);
cy.viewport('iphone-4');
cy.wait(200);
cy.viewport('iphone-3');
cy.wait(200);
// cy.viewport() accepts an orientation for all presets
// the default orientation is 'portrait'
cy.viewport('ipad-2', 'portrait')
cy.wait(200)
cy.viewport('iphone-4', 'landscape')
cy.wait(200)
cy.viewport('ipad-2', 'portrait');
cy.wait(200);
cy.viewport('iphone-4', 'landscape');
cy.wait(200);
// The viewport will be reset back to the default dimensions
// in between tests (the default can be set in cypress.json)
})
})
});
});

View File

@ -2,33 +2,32 @@
context('Waiting', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/waiting')
})
cy.visit('https://example.cypress.io/commands/waiting');
});
// BE CAREFUL of adding unnecessary wait times.
// https://on.cypress.io/best-practices#Unnecessary-Waiting
// https://on.cypress.io/wait
it('cy.wait() - wait for a specific amount of time', () => {
cy.get('.wait-input1').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input2').type('Wait 1000ms after typing')
cy.wait(1000)
cy.get('.wait-input3').type('Wait 1000ms after typing')
cy.wait(1000)
})
cy.get('.wait-input1').type('Wait 1000ms after typing');
cy.wait(1000);
cy.get('.wait-input2').type('Wait 1000ms after typing');
cy.wait(1000);
cy.get('.wait-input3').type('Wait 1000ms after typing');
cy.wait(1000);
});
it('cy.wait() - wait for a specific route', () => {
cy.server()
cy.server();
// Listen to GET to comments/1
cy.route('GET', 'comments/*').as('getComment')
cy.route('GET', 'comments/*').as('getComment');
// we have code that gets a comment when
// the button is clicked in scripts.js
cy.get('.network-btn').click()
cy.get('.network-btn').click();
// wait for GET comments/1
cy.wait('@getComment').its('status').should('eq', 200)
})
})
cy.wait('@getComment').its('status').should('eq', 200);
});
});

View File

@ -2,21 +2,21 @@
context('Window', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/window')
})
cy.visit('https://example.cypress.io/commands/window');
});
it('cy.window() - get the global window object', () => {
// https://on.cypress.io/window
cy.window().should('have.property', 'top')
})
cy.window().should('have.property', 'top');
});
it('cy.document() - get the document object', () => {
// https://on.cypress.io/document
cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
})
cy.document().should('have.property', 'charset').and('eq', 'UTF-8');
});
it('cy.title() - get the title', () => {
// https://on.cypress.io/title
cy.title().should('include', 'Kitchen Sink')
})
})
cy.title().should('include', 'Kitchen Sink');
});
});

View File

@ -1,11 +1,9 @@
/* eslint-env jest */
/* global cy */
import { Base64 } from 'js-base64';
export const mermaidUrl = (graphStr, options, api) => {
const obj = {
code: graphStr,
mermaid: options
mermaid: options,
};
const objStr = JSON.stringify(obj);
let url = 'http://localhost:9000/e2e.html?graph=' + Base64.encodeURI(objStr);

View File

@ -1,5 +1,4 @@
import { renderGraph } from '../../helpers/util';
/* eslint-env jest */
describe('Configuration', () => {
describe('arrowMarkerAbsolute', () => {
it('should handle default value false of arrowMarkerAbsolute', () => {
@ -11,12 +10,14 @@ describe('Configuration', () => {
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{ }
{}
);
// Check the marker-end property to make sure it is properly set to
// start with #
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
cy.get('.edgePath path')
.first()
.should('have.attr', 'marker-end')
.should('exist')
.and('include', 'url(#');
});
@ -29,12 +30,14 @@ describe('Configuration', () => {
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{ }
{}
);
// Check the marker-end property to make sure it is properly set to
// start with #
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
cy.get('.edgePath path')
.first()
.should('have.attr', 'marker-end')
.should('exist')
.and('include', 'url(#');
});
@ -48,13 +51,15 @@ describe('Configuration', () => {
C -->|Three| F[fa:fa-car Car]
`,
{
arrowMarkerAbsolute: false
arrowMarkerAbsolute: false,
}
);
// Check the marker-end property to make sure it is properly set to
// start with #
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
cy.get('.edgePath path')
.first()
.should('have.attr', 'marker-end')
.should('exist')
.and('include', 'url(#');
});
@ -68,13 +73,15 @@ describe('Configuration', () => {
C -->|Three| F[fa:fa-car Car]
`,
{
arrowMarkerAbsolute: "false"
arrowMarkerAbsolute: 'false',
}
);
// Check the marker-end property to make sure it is properly set to
// start with #
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
cy.get('.edgePath path')
.first()
.should('have.attr', 'marker-end')
.should('exist')
.and('include', 'url(#');
});
@ -88,11 +95,13 @@ describe('Configuration', () => {
C -->|Three| F[fa:fa-car Car]
`,
{
arrowMarkerAbsolute: true
arrowMarkerAbsolute: true,
}
);
cy.get('.edgePath path').first().should('have.attr', 'marker-end')
cy.get('.edgePath path')
.first()
.should('have.attr', 'marker-end')
.should('exist')
.and('include', 'url(http://localhost');
});

View File

@ -1,13 +1,10 @@
/* eslint-env jest */
describe('Interaction', () => {
describe('Interaction - security level loose', () => {
it('Graph: should handle a click on a node with a bound function', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-Function-2')
.click();
cy.get('body').find('g#flowchart-Function-2').click();
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
});
@ -15,9 +12,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-FunctionArg-18')
.click();
cy.get('body').find('g#flowchart-FunctionArg-18').click();
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
});
@ -25,9 +20,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-FunctionArg-22"]')
.click();
cy.get('body').find('g[id="flowchart-FunctionArg-22"]').click();
cy.get('.created-by-click-2').should('have.text', 'Clicked By Flow: ARGUMENT');
});
@ -35,11 +28,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('#flowchart-URL-3')
.click();
cy.get('body').find('#flowchart-URL-3').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -47,11 +38,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-2URL-7"]')
.click();
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -60,9 +49,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-Function-10')
.click();
cy.get('body').find('g#flowchart-Function-10').click();
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
});
@ -70,9 +57,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-1Function-14"]')
.click();
cy.get('body').find('g[id="flowchart-1Function-14"]').click();
cy.get('.created-by-click').should('have.text', 'Clicked By Flow');
});
@ -80,11 +65,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('#flowchart-URL-11')
.click();
cy.get('body').find('#flowchart-URL-11').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -92,11 +75,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-2URL-15"]')
.click();
cy.get('body').find('g[id="flowchart-2URL-15"]').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -105,11 +86,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl1')
.click({ force: true });
cy.get('body').find('rect#cl1').click({ force: true });
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -117,11 +96,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl1-text')
.click({ force: true });
cy.get('body').find('text#cl1-text').click({ force: true });
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -129,9 +106,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl2')
.click({ force: true });
cy.get('body').find('rect#cl2').click({ force: true });
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
});
@ -139,9 +114,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl3')
.click({ force: true });
cy.get('body').find('rect#cl3').click({ force: true });
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
});
@ -150,9 +123,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl2-text')
.click({ force: true });
cy.get('body').find('text#cl2-text').click({ force: true });
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant cl2');
});
@ -160,13 +131,10 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_loose.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl3-text')
.click({ force: true });
cy.get('body').find('text#cl3-text').click({ force: true });
cy.get('.created-by-gant-click').should('have.text', 'Clicked By Gant test1 test2 test3');
});
});
describe('Interaction - security level tight', () => {
@ -174,9 +142,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-Function-2')
.click();
cy.get('body').find('g#flowchart-Function-2').click();
cy.get('.created-by-click').should('not.exist');
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
@ -185,9 +151,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-1Function-6"]')
.click();
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
cy.get('.created-by-click').should('not.exist');
@ -196,11 +160,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-URL-3')
.click();
cy.get('body').find('g#flowchart-URL-3').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -208,11 +170,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-2URL-7"]')
.click();
cy.get('body').find('g[id="flowchart-2URL-7"]').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -221,11 +181,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl1')
.click({ force: true });
cy.get('body').find('rect#cl1').click({ force: true });
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -233,11 +191,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl1-text')
.click({ force: true });
cy.get('body').find('text#cl1-text').click({ force: true });
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -245,23 +201,19 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl2')
.click({ force: true });
cy.get('body').find('rect#cl2').click({ force: true });
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
cy.get('.created-by-gant-click').should('not.exist')
cy.get('.created-by-gant-click').should('not.exist');
});
it('should handle a click on a task with a bound function', () => {
const url = 'http://localhost:9000/click_security_strict.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl2-text')
.click({ force: true });
cy.get('body').find('text#cl2-text').click({ force: true });
// cy.get('.created-by-gant-click').should('not.have.text', 'Clicked By Gant cl2');
cy.get('.created-by-gant-click').should('not.exist')
cy.get('.created-by-gant-click').should('not.exist');
});
});
@ -270,9 +222,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_other.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-Function-2')
.click();
cy.get('body').find('g#flowchart-Function-2').click();
// cy.get('.created-by-click').should('not.have.text', 'Clicked By Flow');
cy.get('.created-by-click').should('not.exist');
@ -281,9 +231,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_other.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g[id="flowchart-1Function-6"]')
.click();
cy.get('body').find('g[id="flowchart-1Function-6"]').click();
cy.get('.created-by-click').should('not.exist');
cy.get('.created-by-click').should('not.exist');
@ -292,11 +240,9 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_other.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('g#flowchart-URL-3')
.click();
cy.get('body').find('g#flowchart-URL-3').click();
cy.location().should(location => {
cy.location().should((location) => {
expect(location.href).to.eq('http://localhost:9000/webpackUsage.html');
});
});
@ -305,9 +251,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_other.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('rect#cl2')
.click({ force: true });
cy.get('body').find('rect#cl2').click({ force: true });
cy.get('.created-by-gant-click').should('not.exist');
});
@ -315,9 +259,7 @@ describe('Interaction', () => {
const url = 'http://localhost:9000/click_security_other.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('body')
.find('text#cl2-text')
.click({ force: true });
cy.get('body').find('text#cl2-text').click({ force: true });
cy.get('.created-by-gant-click').should('not.exist');
});

View File

@ -1,22 +1,19 @@
/* eslint-env jest */
describe('Rerendering', () => {
it('should be able to render after an error has occured', () => {
const url = 'http://localhost:9000/render-after-error.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('#graphDiv').should('exist');
});
it('should be able to render after an error has occured', () => {
const url = 'http://localhost:9000/render-after-error.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('#graphDiv').should('exist');
});
it('should be able to render and rerender a graph via API', () => {
const url = 'http://localhost:9000/rerender.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
it('should be able to render and rerender a graph via API', () => {
const url = 'http://localhost:9000/rerender.html';
cy.viewport(1440, 1024);
cy.visit(url);
cy.get('#graph [id^=flowchart-A]').should('have.text', 'XMas');
cy.get('body')
.find('#rerender')
.click({ force: true });
cy.get('body').find('#rerender').click({ force: true });
cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
});
cy.get('#graph [id^=flowchart-A]').should('have.text', 'Saturday');
});
});

View File

@ -1,20 +1,15 @@
/* eslint-env jest */
describe('Sequencediagram', () => {
it('should render a simple sequence diagrams', () => {
const url = 'http://localhost:9000/webpackUsage.html';
cy.visit(url);
cy.get('body')
.find('svg')
.should('have.length', 1);
cy.get('body').find('svg').should('have.length', 1);
});
it('should handle html escapings properly', () => {
const url = 'http://localhost:9000/webpackUsage.html?test-html-escaping=true';
cy.visit(url);
cy.get('body')
.find('svg')
.should('have.length', 1);
cy.get('body').find('svg').should('have.length', 1);
cy.get('g.label > foreignobject > div').should('not.contain.text', '<b>');
});

View File

@ -1,102 +1,108 @@
/* eslint-env jest */
import { mermaidUrl } from '../../helpers/util.js';
/* eslint-disable */
describe('XSS', () => {
it('should handle xss in tags', () => {
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
const str =
'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19';
const url = mermaidUrl(str,{}, true);
const url = mermaidUrl(str, {}, true);
cy.visit(url);
cy.wait(1000).then(()=>{
cy.wait(1000).then(() => {
cy.get('.mermaid').should('exist');
});
cy.get('svg')
})
cy.get('svg');
});
it('should not allow tags in the css', () => {
const str = 'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
const str =
'eyJjb2RlIjoiJSV7aW5pdDogeyAnZm9udEZhbWlseSc6ICdcXFwiPjwvc3R5bGU-PGltZyBzcmM9eCBvbmVycm9yPXhzc0F0dGFjaygpPid9IH0lJVxuZ3JhcGggTFJcbiAgICAgQSAtLT4gQiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX0sInVwZGF0ZUVkaXRvciI6ZmFsc2V9';
const url = mermaidUrl(str,{
"theme": "default",
"flowchart": {
"htmlMode": false
}
}, true);
const url = mermaidUrl(
str,
{
theme: 'default',
flowchart: {
htmlMode: false,
},
},
true
);
cy.visit(url);
cy.wait(1000).then(()=>{
cy.wait(1000).then(() => {
cy.get('#the-malware').should('not.exist');
});
})
});
it('should handle xss in tags in non-html mode', () => {
const str = 'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
const str =
'eyJjb2RlIjoiXG5ncmFwaCBMUlxuICAgICAgQi0tPkQoPGltZyBvbmVycm9yPWxvY2F0aW9uPWBqYXZhc2NyaXB0XFx1MDAzYXhzc0F0dGFja1xcdTAwMjhkb2N1bWVudC5kb21haW5cXHUwMDI5YCBzcmM9eD4pOyIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0IiwiZmxvd2NoYXJ0Ijp7Imh0bWxMYWJlbHMiOmZhbHNlfX19';
const url = mermaidUrl(str,{
"theme": "default",
"flowchart": {
"htmlMode": false
}
}, true);
const url = mermaidUrl(
str,
{
theme: 'default',
flowchart: {
htmlMode: false,
},
},
true
);
cy.visit(url);
cy.wait(1000)
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow changing the __proto__ attribute using config', () => {
cy.visit('http://localhost:9000/xss2.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating htmlLabels into a false positive', () => {
cy.visit('http://localhost:9000/xss4.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript', () => {
cy.visit('http://localhost:9000/xss5.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror', () => {
cy.visit('http://localhost:9000/xss6.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre wrapper', () => {
cy.visit('http://localhost:9000/xss8.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
cy.visit('http://localhost:9000/xss9.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
cy.visit('http://localhost:9000/xss10.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
cy.visit('http://localhost:9000/xss11.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
cy.visit('http://localhost:9000/xss12.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
});
it('should not allow maniplulating antiscript to run javascript using onerror in state diagrams with dagre d3', () => {
cy.visit('http://localhost:9000/xss13.html');
cy.wait(1000);
cy.get('#the-malware').should('not.exist');
})
})
});
});

View File

@ -1,10 +1,8 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util';
describe('Class diagram V2', () => {
it('0: should render a simple class diagram', () => {
imgSnapshotTest(
`
it('0: should render a simple class diagram', () => {
imgSnapshotTest(
`
classDiagram-v2
classA -- classB : Inheritance
@ -13,10 +11,10 @@ describe('Class diagram V2', () => {
classB -- classD
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
);
cy.get('svg');
});
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
it('1: should render a simple class diagram', () => {
imgSnapshotTest(
@ -47,7 +45,7 @@ describe('Class diagram V2', () => {
test()
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -76,8 +74,7 @@ describe('Class diagram V2', () => {
test()
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -95,7 +92,7 @@ describe('Class diagram V2', () => {
Class01 : +int publicGorilla
Class01 : #int protectedMarmoset
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -103,7 +100,7 @@ describe('Class diagram V2', () => {
it('should render multiple class diagrams', () => {
imgSnapshotTest(
[
`
`
classDiagram-v2
Class01 "1" <|--|> "*" AveryLongClass : Cool
&lt;&lt;interface&gt;&gt; Class01
@ -125,7 +122,7 @@ describe('Class diagram V2', () => {
test()
}
`,
`
`
classDiagram-v2
Class01 "1" <|--|> "*" AveryLongClass : Cool
&lt;&lt;interface&gt;&gt; Class01
@ -148,7 +145,7 @@ describe('Class diagram V2', () => {
}
`,
],
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -178,7 +175,7 @@ describe('Class diagram V2', () => {
test()
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -190,7 +187,7 @@ describe('Class diagram V2', () => {
Class01 <|-- AveryLongClass : Cool
Class01 : someMethod()*
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -202,7 +199,7 @@ describe('Class diagram V2', () => {
Class01 <|-- AveryLongClass : Cool
Class01 : someMethod()$
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -222,7 +219,7 @@ describe('Class diagram V2', () => {
test()
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -243,7 +240,7 @@ describe('Class diagram V2', () => {
test()
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -265,7 +262,7 @@ describe('Class diagram V2', () => {
}
link Class01 "google.com" "A Tooltip"
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -287,7 +284,7 @@ describe('Class diagram V2', () => {
}
callback Class01 "functionCall" "A Tooltip"
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -302,7 +299,7 @@ describe('Class diagram V2', () => {
testArray() bool[]
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -318,7 +315,7 @@ describe('Class diagram V2', () => {
testArray() bool[]
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -336,7 +333,7 @@ describe('Class diagram V2', () => {
cssClass "Class10" exClass2
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -352,7 +349,7 @@ describe('Class diagram V2', () => {
testArray() bool[]
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -366,7 +363,7 @@ describe('Class diagram V2', () => {
cssClass "Class10, class20" exClass2
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -379,7 +376,7 @@ describe('Class diagram V2', () => {
+String bar$
}
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -404,7 +401,7 @@ describe('Class diagram V2', () => {
Student "1" --o "1" Bike : rides
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -429,7 +426,7 @@ describe('Class diagram V2', () => {
Student "1" --o "1" Bike : rides
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -453,7 +450,7 @@ describe('Class diagram V2', () => {
Student "1" --o "1" Bike : rides
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});
@ -477,7 +474,7 @@ describe('Class diagram V2', () => {
Student "1" --o "1" Bike : rides
`,
{logLevel : 1, flowchart: { "htmlLabels": false },}
{ logLevel: 1, flowchart: { htmlLabels: false } }
);
cy.get('svg');
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Class diagram', () => {
@ -31,7 +30,7 @@ describe('Class diagram', () => {
test()
}
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});

View File

@ -1,10 +1,9 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Configuration and directives - nodes should be light blue', () => {
it('No config - use default', () => {
imgSnapshotTest(
`
it('No config - use default', () => {
imgSnapshotTest(
`
graph TD
A(Default) --> B[/Another/]
A --> C[End]
@ -13,13 +12,13 @@ describe('Configuration and directives - nodes should be light blue', () => {
C
end
`,
{}
);
cy.get('svg');
});
it('Settigns from intitialize - nodes should be green', () => {
imgSnapshotTest(
`
{}
);
cy.get('svg');
});
it('Settigns from intitialize - nodes should be green', () => {
imgSnapshotTest(
`
graph TD
A(Forest) --> B[/Another/]
A --> C[End]
@ -27,13 +26,13 @@ graph TD
B
C
end `,
{theme:'forest'}
);
cy.get('svg');
});
it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
imgSnapshotTest(
`
{ theme: 'forest' }
);
cy.get('svg');
});
it('Settings from initialize overriding themeVariable - nodes shold be red', () => {
imgSnapshotTest(
`
%%{init: { 'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
@ -45,13 +44,13 @@ graph TD
C
end
`,
{theme:'base', themeVariables:{ primaryColor: '#ff0000'}, logLevel: 0}
);
cy.get('svg');
});
it('Settings from directive - nodes should be grey', () => {
imgSnapshotTest(
`
{ theme: 'base', themeVariables: { primaryColor: '#ff0000' }, logLevel: 0 }
);
cy.get('svg');
});
it('Settings from directive - nodes should be grey', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
graph TD
A(Start) --> B[/Another/]
@ -61,14 +60,14 @@ graph TD
C
end
`,
{}
);
cy.get('svg');
});
{}
);
cy.get('svg');
});
it('Settings from directive overriding theme variable - nodes should be red', () => {
imgSnapshotTest(
`
it('Settings from directive overriding theme variable - nodes should be red', () => {
imgSnapshotTest(
`
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
graph TD
A(Start) --> B[/Another/]
@ -78,13 +77,13 @@ graph TD
C
end
`,
{}
);
cy.get('svg');
{}
);
cy.get('svg');
});
it('Settings from initialize and directive - nodes should be grey', () => {
imgSnapshotTest(
`
it('Settings from initialize and directive - nodes should be grey', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': 'neutral'} }%%
graph TD
A(Start) --> B[/Another/]
@ -94,13 +93,13 @@ graph TD
C
end
`,
{theme:'forest'}
);
cy.get('svg');
});
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
imgSnapshotTest(
`
{ theme: 'forest' }
);
cy.get('svg');
});
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
imgSnapshotTest(
`
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
graph TD
A(Start) --> B[/Another/]
@ -110,13 +109,13 @@ graph TD
C
end
`,
{theme:'base'}
);
cy.get('svg');
});
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
imgSnapshotTest(
`
{ theme: 'base' }
);
cy.get('svg');
});
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
imgSnapshotTest(
`
%%{init: { 'logLevel': 0, 'theme': 'base'} }%%
graph TD
A(Start) --> B[/Another/]
@ -126,16 +125,16 @@ graph TD
C
end
`,
{themeVariables:{primaryColor: '#ff0000'}}
);
{ themeVariables: { primaryColor: '#ff0000' } }
);
cy.get('svg');
});
describe('when rendering several diagrams', () => {
it('diagrams should not taint later diagrams', () => {
const url = 'http://localhost:9000/theme-directives.html';
cy.visit(url);
cy.get('svg');
});
describe('when rendering several diagrams', () => {
it('diagrams should not taint later diagrams', () => {
const url = 'http://localhost:9000/theme-directives.html';
cy.visit(url);
cy.get('svg');
cy.percySnapshot();
});
cy.percySnapshot();
});
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util';
describe('State diagram', () => {

View File

@ -1,14 +1,12 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util';
describe('Flowchart', () => {
it('34: testing the label width in percy', () => {
imgSnapshotTest(
`graph TD
A[Christmas]
`,
{ theme: 'forest' , fontFamily: '"Noto Sans SC", sans-serif' }
{ theme: 'forest', fontFamily: '"Noto Sans SC", sans-serif' }
);
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Entity Relationship Diagram', () => {
@ -9,7 +8,7 @@ describe('Entity Relationship Diagram', () => {
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -22,7 +21,7 @@ describe('Entity Relationship Diagram', () => {
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -34,7 +33,7 @@ describe('Entity Relationship Diagram', () => {
CUSTOMER ||--|{ ADDRESS : "invoiced at"
CUSTOMER ||--|{ ADDRESS : "receives goods at"
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -47,7 +46,7 @@ describe('Entity Relationship Diagram', () => {
B ||--|{ C : likes
C ||--|{ A : likes
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -65,7 +64,7 @@ describe('Entity Relationship Diagram', () => {
PRODUCT-CATEGORY ||--|{ PRODUCT : contains
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -73,18 +72,18 @@ describe('Entity Relationship Diagram', () => {
it('should render multiple ER diagrams', () => {
imgSnapshotTest(
[
`
`
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
`,
`
`
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
`
`,
],
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -97,7 +96,7 @@ describe('Entity Relationship Diagram', () => {
BOOK }|..|{ GENRE : " "
AUTHOR }|..|{ GENRE : " "
`,
{logLevel : 1}
{ logLevel: 1 }
);
cy.get('svg');
});
@ -111,16 +110,15 @@ describe('Entity Relationship Diagram', () => {
`,
{ er: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height', '465');
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(140 * .95, 140 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height', '465');
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(140 * 0.95, 140 * 1.05);
});
});
it('should render an ER when useMaxWidth is false', () => {
@ -132,14 +130,13 @@ describe('Entity Relationship Diagram', () => {
`,
{ er: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(140 * .95, 140 * 1.05);
expect(svg).to.have.attr('height', '465');
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(140 * 0.95, 140 * 1.05);
expect(svg).to.have.attr('height', '465');
expect(svg).to.not.have.attr('style');
});
});
it('should render entities that have no relationships', () => {
@ -165,7 +162,7 @@ describe('Entity Relationship Diagram', () => {
AUTHOR }|..|{ BOOK : writes
BOOK { float price }
`,
{ logLevel : 1 }
{ logLevel: 1 }
);
cy.get('svg');
});
@ -181,7 +178,7 @@ describe('Entity Relationship Diagram', () => {
PRIVATE_FINANCIAL_INSTITUTION ||..|{ EMPLOYEE : employs
EMPLOYEE { bool officer_of_firm }
`,
{ logLevel : 1 }
{ logLevel: 1 }
);
cy.get('svg');
});
@ -192,9 +189,8 @@ describe('Entity Relationship Diagram', () => {
erDiagram
BOOK { string title PK "comment"}
`,
{ logLevel : 1 }
{ logLevel: 1 }
);
cy.get('svg');
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Flowchart v2', () => {
@ -29,7 +28,7 @@ describe('Flowchart v2', () => {
);
});
it('3: a link with correct arrowhead to a subgraph', () => {
it('3: a link with correct arrowhead to a subgraph', () => {
imgSnapshotTest(
`flowchart TD
P1
@ -69,7 +68,7 @@ describe('Flowchart v2', () => {
`flowchart TD
a["<strong>Haiya</strong>"]---->b
`,
{htmlLabels: false, flowchart: {htmlLabels: false}}
{ htmlLabels: false, flowchart: { htmlLabels: false } }
);
});
it('6: should render non-escaped with html labels', () => {
@ -77,7 +76,7 @@ describe('Flowchart v2', () => {
`flowchart TD
a["<strong>Haiya</strong>"]===>b
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('7: should render a flowchart when useMaxWidth is true (default)', () => {
@ -91,18 +90,17 @@ describe('Flowchart v2', () => {
`,
{ flowchart: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * .95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(290 * .95-1, 290 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(290 * 0.95 - 1, 290 * 1.05);
});
});
it('8: should render a flowchart when useMaxWidth is false', () => {
renderGraph(
@ -115,15 +113,14 @@ describe('Flowchart v2', () => {
`,
{ flowchart: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * .95, 446 * 1.05);
expect(width).to.be.within(290 * .95-1, 290 * 1.05);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
expect(width).to.be.within(290 * 0.95 - 1, 290 * 1.05);
expect(svg).to.not.have.attr('style');
});
});
it('V2 - 16: Render Stadium shape', () => {
@ -141,7 +138,7 @@ describe('Flowchart v2', () => {
class A someclass;
class C someclass;
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -156,7 +153,7 @@ describe('Flowchart v2', () => {
b
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -171,7 +168,7 @@ describe('Flowchart v2', () => {
b
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -192,7 +189,7 @@ describe('Flowchart v2', () => {
B
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -222,7 +219,7 @@ describe('Flowchart v2', () => {
routeur --> subnet1 & subnet2
subnet1 & subnet2 --> nat --> internet
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -236,7 +233,7 @@ describe('Flowchart v2', () => {
subcontainer-child--> subcontainer-sibling
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -258,11 +255,10 @@ end
sub_one --> sub_two
_one --> b
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('56: handle nested subgraphs with outgoing links 3', () => {
imgSnapshotTest(
`flowchart TB
@ -275,7 +271,7 @@ _one --> b
end
process_B-->|via_AWSBatch|container_Beta
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('57: handle nested subgraphs with outgoing links 4', () => {
@ -288,11 +284,10 @@ subgraph B
b
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('57: handle nested subgraphs with outgoing links 2', () => {
imgSnapshotTest(
`flowchart TB
@ -310,7 +305,7 @@ end
three --> two
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('57.x: handle nested subgraphs with outgoing links 5', () => {
@ -326,7 +321,7 @@ flowchart TB
process_A-->|messages|process_C
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('58: handle styling with style expressions', () => {
@ -337,7 +332,7 @@ flowchart TB
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('59: handle styling of subgraphs and links', () => {
@ -359,7 +354,7 @@ flowchart TD
class T TestSub
linkStyle 0,1 color:orange, stroke: orange;
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('60: handle styling for all node shapes - v2', () => {
@ -389,7 +384,7 @@ flowchart TD
style M stroke:#ff0000,fill:#ffcccc,color:#ff0000;
style N stroke:#0000ff,fill:#ccccff,color:#0000ff;
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose', logLevel:2}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose', logLevel: 2 }
);
});
it('61: fontawesome icons in edge labels', () => {
@ -398,7 +393,7 @@ flowchart TD
flowchart TD
C -->|fa:fa-car Car| F[fa:fa-car Car]
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('62: should render styled subgraphs', () => {
@ -432,7 +427,7 @@ flowchart TD
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('63: title on subgraphs should be themable', () => {
@ -448,7 +443,7 @@ flowchart TD
end
A --> B
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('65: text-color from classes', () => {
@ -459,7 +454,7 @@ flowchart TD
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('66: More nested subgraph cases (TB)', () => {
@ -477,7 +472,7 @@ flowchart TB
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('67: More nested subgraph cases (RL)', () => {
@ -495,7 +490,7 @@ flowchart RL
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('68: More nested subgraph cases (BT)', () => {
@ -513,7 +508,7 @@ flowchart BT
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('69: More nested subgraph cases (LR)', () => {
@ -531,7 +526,7 @@ flowchart LR
two --> c2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('70: Handle nested subgraph cases (TB) link out and link between subgraphs', () => {
@ -547,7 +542,7 @@ flowchart TB
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('71: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
@ -563,7 +558,7 @@ flowchart RL
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('72: Handle nested subgraph cases (BT) link out and link between subgraphs', () => {
@ -579,7 +574,7 @@ flowchart BT
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('74: Handle nested subgraph cases (RL) link out and link between subgraphs', () => {
@ -595,10 +590,10 @@ flowchart RL
S1 --> S2
sub1 --> sub4
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
it('74: Handle labels for multiple edges from and to the same couple of nodes', () => {
imgSnapshotTest(
`
flowchart RL
@ -607,7 +602,7 @@ flowchart RL
a1 -- l2 --> a2
end
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
@ -617,11 +612,11 @@ flowchart RL
a{{"Lorem 'ipsum' dolor 'sit' amet, 'consectetur' adipiscing 'elit'."}}
--> b{{"Lorem #quot;ipsum#quot; dolor #quot;sit#quot; amet,#quot;consectetur#quot; adipiscing #quot;elit#quot;."}}
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('2050: handling of different rendering direction in subgraphs', () => {
it('2050: handling of different rendering direction in subgraphs', () => {
imgSnapshotTest(
`
flowchart LR
@ -640,7 +635,7 @@ flowchart RL
A --> TOP --> B
B1 --> B2
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('Graph', () => {
@ -38,7 +37,7 @@ describe('Graph', () => {
C -->|Two| E[iPhone]
C -->|Three| F[Car]
`,
{fontFamily: 'courier'}
{ fontFamily: 'courier' }
);
});
@ -53,7 +52,7 @@ describe('Graph', () => {
C -->|Two| E[\\iPhone\\]
C -->|Three| F[Car]
`,
{ fontFamily: 'courier'}
{ fontFamily: 'courier' }
);
});
@ -69,7 +68,7 @@ describe('Graph', () => {
classDef processHead fill:#888888,color:white,font-weight:bold,stroke-width:3px,stroke:#001f3f
class 1A,1B,D,E processHead
`,
{fontFamily: 'courier'}
{ fontFamily: 'courier' }
);
});
@ -98,7 +97,7 @@ describe('Graph', () => {
35(SAM.CommonFA.PopulationFME)-->39(SAM.CommonFA.ChargeDetails)
36(SAM.CommonFA.PremetricCost)-->39(SAM.CommonFA.ChargeDetails)
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -169,7 +168,7 @@ describe('Graph', () => {
9a072290_1ec3_e711_8c5a_005056ad0002-->d6072290_1ec3_e711_8c5a_005056ad0002
9a072290_1ec3_e711_8c5a_005056ad0002-->71082290_1ec3_e711_8c5a_005056ad0002
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -178,7 +177,7 @@ describe('Graph', () => {
`
graph TB;subgraph "number as labels";1;end;
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -190,7 +189,7 @@ describe('Graph', () => {
a1-->a2
end
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -202,7 +201,7 @@ describe('Graph', () => {
a1-->a2
end
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -237,7 +236,7 @@ describe('Graph', () => {
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -339,7 +338,7 @@ describe('Graph', () => {
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4DA958A0-26D9-4D47-93A7-70F39FD7D51A;
sid-7CE72B24-E0C1-46D3-8132-8BA66BE05AA7-->sid-4FC27B48-A6F9-460A-A675-021F5854FE22;
`,
{ fontFamily: 'courier' }
{ fontFamily: 'courier' }
);
});
@ -357,7 +356,7 @@ describe('Graph', () => {
listUrl: false,
listId: 'color styling',
fontFamily: 'courier',
logLevel: 0
logLevel: 0,
}
);
});
@ -379,8 +378,9 @@ describe('Graph', () => {
`,
{
listUrl: false,
listId: 'color styling', fontFamily: 'courier',
logLevel: 0
listId: 'color styling',
fontFamily: 'courier',
logLevel: 0,
}
);
});
@ -395,7 +395,7 @@ describe('Graph', () => {
C -->|Two| E[iPhone]
C -->|Three| F[fa:fa-car Car]
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -414,7 +414,7 @@ describe('Graph', () => {
class A someclass;
class C someclass;
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -431,7 +431,7 @@ describe('Graph', () => {
linkStyle 1 stroke:DarkGray,stroke-width:2px
linkStyle 2 stroke:DarkGray,stroke-width:2px
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -440,7 +440,7 @@ describe('Graph', () => {
`graph LR
a --> b --> c
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -449,7 +449,7 @@ describe('Graph', () => {
`graph LR
a --> b & c--> d
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -459,7 +459,7 @@ describe('Graph', () => {
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;
classDef exClass background:#bbb,border:1px solid red;
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -481,7 +481,7 @@ describe('Graph', () => {
click B testClick "click test"
classDef someclass fill:#f96;
class A someclass;`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -522,7 +522,7 @@ describe('Graph', () => {
linkStyle 1 stroke:greenyellow,stroke-width:2px
style C fill:greenyellow,stroke:green,stroke-width:4px
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -545,7 +545,7 @@ describe('Graph', () => {
click F "javascript:alert('test')" "script test"
`,
{ securityLevel: 'loose', fontFamily: 'courier' }
);
);
});
it('26: Set text color of nodes and links according to styles when html labels are enabled', () => {
@ -584,7 +584,7 @@ describe('Graph', () => {
click B "index.html#link-clicked" "link test"
click D testClick "click test"
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -616,7 +616,7 @@ describe('Graph', () => {
class A myClass1
class D myClass2
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -640,7 +640,7 @@ describe('Graph', () => {
classDef redBg fill:#622;
classDef whiteTxt color: white;
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -652,7 +652,7 @@ describe('Graph', () => {
eat --> sleep
work --> eat
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -671,7 +671,7 @@ describe('Graph', () => {
class A someclass;
class C someclass;
`,
{ flowchart: { htmlLabels: false } , fontFamily: 'courier'}
{ flowchart: { htmlLabels: false }, fontFamily: 'courier' }
);
});
@ -694,7 +694,7 @@ describe('Graph', () => {
`graph TD
A[Christmas]
`,
{ }
{}
);
});
@ -712,7 +712,7 @@ describe('Graph', () => {
C -----> E4
C ======> E5
`,
{ }
{}
);
});
it('36: should render escaped without html labels', () => {
@ -720,7 +720,7 @@ describe('Graph', () => {
`graph TD
a["<strong>Haiya</strong>"]-->b
`,
{htmlLabels: false, flowchart: {htmlLabels: false}}
{ htmlLabels: false, flowchart: { htmlLabels: false } }
);
});
it('37: should render non-escaped with html labels', () => {
@ -728,7 +728,7 @@ describe('Graph', () => {
`graph TD
a["<strong>Haiya</strong>"]-->b
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('38: should render a flowchart when useMaxWidth is true (default)', () => {
@ -742,18 +742,17 @@ describe('Graph', () => {
`,
{ flowchart: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * .95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(300 * .95, 300 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(300 * 0.95, 300 * 1.05);
});
});
it('39: should render a flowchart when useMaxWidth is false', () => {
renderGraph(
@ -766,15 +765,14 @@ describe('Graph', () => {
`,
{ flowchart: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * .95, 446 * 1.05);
expect(width).to.be.within(300 * .95, 300 * 1.05);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(446 * 0.95, 446 * 1.05);
expect(width).to.be.within(300 * 0.95, 300 * 1.05);
expect(svg).to.not.have.attr('style');
});
});
it('58: handle styling with style expressions', () => {
imgSnapshotTest(
@ -784,7 +782,7 @@ describe('Graph', () => {
style id1 fill:#f9f,stroke:#333,stroke-width:4px
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('60: handle styling for all node shapes', () => {
@ -808,7 +806,7 @@ describe('Graph', () => {
style I stroke:#ff0000,fill:#ffcccc,color:#ff0000
style J stroke:#0000ff,fill:#ccccff,color:#0000ff
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('61: fontawesome icons in edge labels', () => {
@ -817,7 +815,7 @@ describe('Graph', () => {
graph TD
C -->|fa:fa-car Car| F[fa:fa-car Car]
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('62: fontawesome icons in edge labels', () => {
@ -829,7 +827,7 @@ graph TD
end
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('63: fontawesome icons in edge labels', () => {
@ -863,7 +861,7 @@ graph TD
style foo fill:#F99,stroke-width:2px,stroke:#F0F,color:darkred
style bar fill:#999,stroke-width:10px,stroke:#0F0,color:blue
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('64: fontawesome icons in edge labels', () => {
@ -879,7 +877,7 @@ graph TD
end
A --> B
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
it('65: text-color from classes', () => {
@ -890,7 +888,7 @@ graph TD
Lorem --> Ipsum --> Dolor
class Lorem,Dolor dark
`,
{htmlLabels: true, flowchart: {htmlLabels: true}, securityLevel: 'loose'}
{ htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' }
);
});
});

View File

@ -1,10 +1,9 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Gantt diagram', () => {
beforeEach(()=>{
cy.clock((new Date('1010-10-10')).getTime())
})
beforeEach(() => {
cy.clock(new Date('1010-10-10').getTime());
});
it('should render a gantt chart', () => {
imgSnapshotTest(
`
@ -199,18 +198,17 @@ describe('Gantt diagram', () => {
`,
{ gantt: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(484 * .95, 484 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(984 * .95, 984 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
// use within because the absolute value can be slightly different depending on the environment ±5%
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.be.within(984 * 0.95, 984 * 1.05);
});
});
it('should render a gantt diagram when useMaxWidth is false', () => {
@ -248,17 +246,16 @@ describe('Gantt diagram', () => {
`,
{ gantt: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(484 * .95, 484 * 1.05);
expect(width).to.be.within(984 * .95, 984 * 1.05);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(height).to.be.within(484 * 0.95, 484 * 1.05);
expect(width).to.be.within(984 * 0.95, 984 * 1.05);
expect(svg).to.not.have.attr('style');
});
});
it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
it('should render a gantt diagram with data labels at the top when topAxis is true', () => {
imgSnapshotTest(
`
gantt

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Sequencediagram', () => {

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Sequencediagram', () => {

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('User journey diagram', () => {
@ -40,17 +39,16 @@ section Checkout from website
`,
{ journey: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(565);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.eq(700);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(565);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.eq(700);
});
});
it('should render a user journey diagram when useMaxWidth is false', () => {

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Pie Chart', () => {
@ -47,17 +46,16 @@ describe('Pie Chart', () => {
`,
{ pie: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(450);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.eq(984);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.eq(450);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
expect(maxWidthValue).to.eq(984);
});
});
it('should render a pie diagram when useMaxWidth is false', () => {
renderGraph(
@ -69,13 +67,12 @@ describe('Pie Chart', () => {
`,
{ pie: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.eq(450);
expect(width).to.eq(984);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.eq(450);
expect(width).to.eq(984);
expect(svg).to.not.have.attr('style');
});
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
describe('Requirement diagram', () => {

View File

@ -29,7 +29,7 @@ context('Sequence diagram', () => {
Alice -->> John: Parallel message 2
end
`,
{sequence:{actorFontFamily:'courier'}}
{ sequence: { actorFontFamily: 'courier' } }
);
});
it('should handle different line breaks', () => {
@ -71,7 +71,7 @@ context('Sequence diagram', () => {
`,
{}
);
})
});
it('should render loops with a slight margin', () => {
imgSnapshotTest(
`
@ -147,7 +147,7 @@ context('Sequence diagram', () => {
A->>Bob: Hola
Bob-->A: Pasten !
`,
{logLevel: 0}
{ logLevel: 0 }
);
});
it('should wrap (inline) long actor descriptions', () => {
@ -158,7 +158,7 @@ context('Sequence diagram', () => {
A->>Bob: Hola
Bob-->A: Pasten !
`,
{logLevel: 0}
{ logLevel: 0 }
);
});
it('should wrap (directive) long actor descriptions', () => {
@ -527,17 +527,17 @@ context('Sequence diagram', () => {
});
it('should render with an init directive', () => {
imgSnapshotTest(
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
`%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "fontWeight": 400, "wrap": true }}}%%
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!`,
{}
)
);
});
});
context('directives', () => {
it('should override config with directive settings', () => {
it('should override config with directive settings', () => {
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": true }}}%%
@ -546,10 +546,13 @@ context('Sequence diagram', () => {
note left of Alice: config set to mirrorActors: false<br/>directive set to mirrorActors: true
Bob->>Alice: Short as well
`,
{ logLevel:0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
{
logLevel: 0,
sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
}
);
});
it('should override config with directive settings', () => {
it('should override config with directive settings', () => {
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": false, "wrap": true }}}%%
@ -558,13 +561,13 @@ context('Sequence diagram', () => {
note left of Alice: config: mirrorActors=true<br/>directive: mirrorActors=false
Bob->>Alice: Short as well
`,
{ logLevel:0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
{ logLevel: 0, sequence: { mirrorActors: true, noteFontSize: 18, noteFontFamily: 'Arial' } }
);
});
});
context('links', () => {
it('should support actor links and properties EXPERIMENTAL: USE WITH CAUTION', () => {
//Be aware that the syntax for "properties" is likely to be changed.
//Be aware that the syntax for "properties" is likely to be changed.
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": true, "forceMenus": true }}}%%
@ -585,7 +588,7 @@ context('Sequence diagram', () => {
);
});
it('should support actor links and properties when not mirrored EXPERIMENTAL: USE WITH CAUTION', () => {
//Be aware that the syntax for "properties" is likely to be changed.
//Be aware that the syntax for "properties" is likely to be changed.
imgSnapshotTest(
`
%%{init: { "config": { "mirrorActors": false, "forceMenus": true, "wrap": true }}}%%
@ -601,7 +604,10 @@ context('Sequence diagram', () => {
a->>j: Hello John, how are you?
j-->>a: Great!
`,
{ logLevel: 0, sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' } }
{
logLevel: 0,
sequence: { mirrorActors: false, noteFontSize: 18, noteFontFamily: 'Arial' },
}
);
});
});
@ -634,18 +640,17 @@ context('Sequence diagram', () => {
`,
{ sequence: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(920, 960);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(820 * .95, 820 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(920, 960);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(820 * 0.95, 820 * 1.05);
});
});
it('should render a sequence diagram when useMaxWidth is false', () => {
renderGraph(
@ -675,15 +680,14 @@ context('Sequence diagram', () => {
`,
{ sequence: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(920, 960);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(820 * .95, 820 * 1.05);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(920, 960);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(820 * 0.95, 820 * 1.05);
expect(svg).to.not.have.attr('style');
});
});
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('State diagram', () => {
@ -369,7 +368,8 @@ stateDiagram-v2
}
`,
{
logLevel: 0, fontFamily: 'courier'
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -381,7 +381,8 @@ stateDiagram-v2
a --> b: Stop
`,
{
logLevel: 0, fontFamily: 'courier',
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -394,7 +395,8 @@ stateDiagram-v2
note right of MyState : I am a rightie
`,
{
logLevel: 0, fontFamily: 'courier',
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -414,7 +416,8 @@ stateDiagram-v2
A --> C
`,
{
logLevel: 0, fontFamily: 'courier',
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -433,7 +436,8 @@ stateDiagram-v2
sub1 --> sub4
`,
{
logLevel: 0, fontFamily: 'courier',
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -447,18 +451,17 @@ stateDiagram-v2
`,
{ state: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(177, 178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(135 * .95, 135 * 1.05);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(177, 178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(maxWidthValue).to.be.within(135 * 0.95, 135 * 1.05);
});
});
it('v2 should render a state diagram when useMaxWidth is false', () => {
renderGraph(
@ -470,14 +473,13 @@ stateDiagram-v2
`,
{ state: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(177, 178);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(135 * .95, 135 * 1.05);
expect(svg).to.not.have.attr('style');
});
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(177, 178);
// use within because the absolute value can be slightly different depending on the environment ±5%
expect(width).to.be.within(135 * 0.95, 135 * 1.05);
expect(svg).to.not.have.attr('style');
});
});
});

View File

@ -1,4 +1,3 @@
/* eslint-env jest */
import { imgSnapshotTest, renderGraph } from '../../helpers/util';
describe('State diagram', () => {
@ -315,7 +314,8 @@ describe('State diagram', () => {
}
`,
{
logLevel: 0, fontFamily: 'courier'
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -328,7 +328,8 @@ describe('State diagram', () => {
}
`,
{
logLevel: 0, fontFamily: 'courier'
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -340,7 +341,8 @@ describe('State diagram', () => {
a --> b: Stop
`,
{
logLevel: 0, fontFamily: 'courier'
logLevel: 0,
fontFamily: 'courier',
}
);
});
@ -353,20 +355,19 @@ describe('State diagram', () => {
`,
{ state: { useMaxWidth: true } }
);
cy.get('svg')
.should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(176,178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
expect(maxWidthValue).to.be.within(130, 140);
});
cy.get('svg').should((svg) => {
expect(svg).to.have.attr('width', '100%');
expect(svg).to.have.attr('height');
const height = parseFloat(svg.attr('height'));
expect(height).to.be.within(176, 178);
const style = svg.attr('style');
expect(style).to.match(/^max-width: [\d.]+px;$/);
const maxWidthValue = parseFloat(style.match(/[\d.]+/g).join(''));
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(maxWidthValue).to.be.within(112 * .95, 112 * 1.05);
expect(maxWidthValue).to.be.within(130, 140);
});
});
it('should render a state diagram when useMaxWidth is false', () => {
renderGraph(
@ -377,17 +378,16 @@ describe('State diagram', () => {
`,
{ state: { useMaxWidth: false } }
);
cy.get('svg')
.should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(176,178);
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(width).to.be.within(112 * .95, 112 * 1.05);
expect(width).to.be.within(130, 140);
cy.get('svg').should((svg) => {
const height = parseFloat(svg.attr('height'));
const width = parseFloat(svg.attr('width'));
expect(height).to.be.within(176, 178);
// use within because the absolute value can be slightly different depending on the environment ±5%
// Todo investigate difference
// expect(width).to.be.within(112 * .95, 112 * 1.05);
expect(width).to.be.within(130, 140);
expect(svg).to.not.have.attr('style');
});
expect(svg).to.not.have.attr('style');
});
});
});

View File

@ -1,12 +1,11 @@
/* eslint-env jest */
import { imgSnapshotTest } from '../../helpers/util.js';
describe('Pie Chart', () => {
// beforeEach(()=>{
// cy.clock((new Date('2014-06-09')).getTime());
// });
// beforeEach(()=>{
// cy.clock((new Date('2014-06-09')).getTime());
// });
['default', 'forest', 'dark', 'neutral'].forEach(theme=>{
['default', 'forest', 'dark', 'neutral'].forEach((theme) => {
describe(theme, () => {
it('should render a pie diagram', () => {
imgSnapshotTest(
@ -16,7 +15,7 @@ describe('Pie Chart', () => {
"Ice-Hockey" : 80
"Football" : 90
`,
{theme}
{ theme }
);
cy.get('svg');
});
@ -39,7 +38,7 @@ describe('Pie Chart', () => {
G
end
`,
{theme}
{ theme }
);
cy.get('svg');
});
@ -62,7 +61,7 @@ describe('Pie Chart', () => {
G
end
`,
{theme}
{ theme }
);
cy.get('svg');
});
@ -88,7 +87,7 @@ describe('Pie Chart', () => {
`,
{theme}
{ theme }
);
cy.get('svg');
});
@ -135,10 +134,10 @@ describe('Pie Chart', () => {
classM ..|> classN : Realization
classO .. classP : Link(Dashed)
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
it('should render a state diagram', () => {
imgSnapshotTest(
`
@ -167,10 +166,10 @@ stateDiagram
Active --> SomethingElse
note right of SomethingElse : This is the note to the right.
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
it('should render a state diagram (v2)', () => {
imgSnapshotTest(
`
@ -199,10 +198,10 @@ stateDiagram-v2
Active --> SomethingElse2
note right of SomethingElse2 : This is the note to the right.
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
it('should render a er diagram', () => {
imgSnapshotTest(
`
@ -217,10 +216,10 @@ erDiagram
PRODUCT ||--o{ ORDER-ITEM : "ordered in"
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
it('should render a user journey diagram', () => {
imgSnapshotTest(
`
@ -235,12 +234,12 @@ erDiagram
Go downstairs: 5: Me
Sit down: 5: Me
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
it('should render a gantt diagram', () => {
cy.clock((new Date('2014-01-06')).getTime());
cy.clock(new Date('2014-01-06').getTime());
imgSnapshotTest(
`
gantt
@ -271,10 +270,10 @@ erDiagram
Add gantt diagram to demo page :20h
Add another diagram to demo page :48h
`,
{theme}
{ theme }
);
cy.get('svg');
});
});
});
});
});

View File

@ -30,30 +30,29 @@ if (location.href.match('test-html-escaping')) {
code = code3;
}
mermaid.initialize({
theme: 'default',
// fontFamily: '"Lucida Console", Monaco, monospace',
startOnLoad: false,
securityLevel: 'loose',
flowchart: {
htmlLabels: true
htmlLabels: true,
},
gantt: {
axisFormatter: [
[
'%Y-%m-%d',
d => {
(d) => {
return d.getDay() === 1;
}
]
]
}
},
],
],
},
});
mermaid.render(
'the-id-of-the-svg',
code,
svg => {
(svg) => {
console.log(svg);
const elem = document.querySelector('#graph-to-be');
elem.innerHTML = svg;

View File

@ -2,11 +2,10 @@ import { Base64 } from 'js-base64';
import mermaid2 from '../../src/mermaid';
/**
* ##contentLoaded
* Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
* calls init for rendering the mermaid diagrams on the page.
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the page.
*/
const contentLoaded = function() {
const contentLoaded = function () {
let pos = document.location.href.indexOf('?graph=');
if (pos > 0) {
pos = pos + 7;
@ -38,8 +37,12 @@ const contentLoaded = function() {
}
};
/**
* @param current
* @param update
*/
function merge(current, update) {
Object.keys(update).forEach(function(key) {
Object.keys(update).forEach(function (key) {
// if update[key] exist, and it's not a string or array,
// we go in one level deeper
if (
@ -58,7 +61,7 @@ function merge(current, update) {
return current;
}
const contentLoadedApi = function() {
const contentLoadedApi = function () {
let pos = document.location.href.indexOf('?graph=');
if (pos > 0) {
pos = pos + 7;
@ -125,7 +128,7 @@ if (typeof document !== 'undefined') {
*/
window.addEventListener(
'load',
function() {
function () {
if (this.location.href.match('xss.html')) {
this.console.log('Using api');
contentLoadedApi();

View File

@ -16,8 +16,7 @@
// // `config` is the resolved Cypress config
// }
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
};
};

View File

@ -24,4 +24,4 @@
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
import '@percy/cypress'
import '@percy/cypress';

View File

@ -30123,7 +30123,7 @@ module.exports = require("stylis");
/***/ ((module) => {
"use strict";
module.exports = JSON.parse('{"name":"mermaid","version":"8.13.4","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","module":"dist/mermaid.esm.min.mjs","exports":{".":{"require":"./dist/mermaid.core.js","import":"./dist/mermaid.esm.min.mjs"},"./*":"./*"},"keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build:development":"webpack --progress --color","build:production":"yarn build:development --mode production --config webpack.config.prod.babel.js","build":"concurrently \\"yarn build:development\\" \\"yarn build:production\\"","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 src","lint:fix":"yarn lint --fix","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack serve --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn test","prepare":"yarn build"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","d3":"^7.0.0","dagre":"^0.8.5","dagre-d3":"^0.6.4","dompurify":"2.3.3","graphlib":"^2.1.8","khroma":"^1.4.1","moment-mini":"^2.24.0","stylis":"^4.0.10"},"devDependencies":{"@babel/core":"^7.14.6","@babel/eslint-parser":"^7.14.7","@babel/preset-env":"^7.14.7","@babel/register":"^7.14.5","@percy/cli":"^1.0.0-beta.58","@percy/cypress":"^3.1.0","@percy/migrate":"^0.11.0","babel-jest":"^27.0.6","babel-loader":"^8.2.2","concurrently":"^6.2.2","coveralls":"^3.0.2","css-to-string-loader":"^0.1.3","cypress":"8.7.0","documentation":"13.2.0","eslint":"^8.0.0","eslint-config-prettier":"^8.3.0","eslint-plugin-jsdoc":"^37.0.3","eslint-plugin-prettier":"^4.0.0","husky":"^7.0.1","identity-obj-proxy":"^3.0.0","jest":"^27.0.6","jison":"^0.4.18","js-base64":"3.7.2","moment":"^2.23.0","path-browserify":"^1.0.1","prettier":"^2.3.2","prettier-plugin-jsdoc":"^0.3.30","start-server-and-test":"^1.12.6","terser-webpack-plugin":"^5.2.4","webpack":"^5.53.0","webpack-cli":"^4.7.2","webpack-dev-server":"^4.3.0","webpack-node-externals":"^3.0.0"},"files":["dist"],"sideEffects":["**/*.css","**/*.scss"],"husky":{"hooks":{"pre-push":"yarn test"}}}');
module.exports = JSON.parse('{"name":"mermaid","version":"8.13.4","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","module":"dist/mermaid.esm.min.mjs","exports":{".":{"require":"./dist/mermaid.core.js","import":"./dist/mermaid.esm.min.mjs"},"./*":"./*"},"keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build:development":"webpack --progress --color","build:production":"yarn build:development --mode production --config webpack.config.prod.babel.js","build":"concurrently \\"yarn build:development\\" \\"yarn build:production\\"","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 .","lint:fix":"yarn lint --fix","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack serve --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn test","prepare":"yarn build"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","d3":"^7.0.0","dagre":"^0.8.5","dagre-d3":"^0.6.4","dompurify":"2.3.3","graphlib":"^2.1.8","khroma":"^1.4.1","moment-mini":"^2.24.0","stylis":"^4.0.10"},"devDependencies":{"@babel/core":"^7.14.6","@babel/eslint-parser":"^7.14.7","@babel/preset-env":"^7.14.7","@babel/register":"^7.14.5","@percy/cli":"^1.0.0-beta.58","@percy/cypress":"^3.1.0","@percy/migrate":"^0.11.0","babel-jest":"^27.0.6","babel-loader":"^8.2.2","concurrently":"^6.2.2","coveralls":"^3.0.2","css-to-string-loader":"^0.1.3","cypress":"9.0.0","documentation":"13.2.0","eslint":"^8.2.0","eslint-config-prettier":"^8.3.0","eslint-plugin-cypress":"^2.12.1","eslint-plugin-jest":"^25.2.4","eslint-plugin-jsdoc":"^37.0.3","eslint-plugin-prettier":"^4.0.0","husky":"^7.0.1","identity-obj-proxy":"^3.0.0","jest":"^27.0.6","jison":"^0.4.18","js-base64":"3.7.2","moment":"^2.23.0","path-browserify":"^1.0.1","prettier":"^2.3.2","prettier-plugin-jsdoc":"^0.3.30","start-server-and-test":"^1.12.6","terser-webpack-plugin":"^5.2.4","webpack":"^5.53.0","webpack-cli":"^4.7.2","webpack-dev-server":"^4.3.0","webpack-node-externals":"^3.0.0"},"files":["dist"],"sideEffects":["**/*.css","**/*.scss"],"husky":{"hooks":{"pre-push":"yarn test"}}}');
/***/ })

File diff suppressed because one or more lines are too long

2
dist/mermaid.js vendored
View File

@ -127562,7 +127562,7 @@ function combine (array, callback) {
/***/ ((module) => {
"use strict";
module.exports = JSON.parse('{"name":"mermaid","version":"8.13.4","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","module":"dist/mermaid.esm.min.mjs","exports":{".":{"require":"./dist/mermaid.core.js","import":"./dist/mermaid.esm.min.mjs"},"./*":"./*"},"keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build:development":"webpack --progress --color","build:production":"yarn build:development --mode production --config webpack.config.prod.babel.js","build":"concurrently \\"yarn build:development\\" \\"yarn build:production\\"","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 src","lint:fix":"yarn lint --fix","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack serve --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn test","prepare":"yarn build"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","d3":"^7.0.0","dagre":"^0.8.5","dagre-d3":"^0.6.4","dompurify":"2.3.3","graphlib":"^2.1.8","khroma":"^1.4.1","moment-mini":"^2.24.0","stylis":"^4.0.10"},"devDependencies":{"@babel/core":"^7.14.6","@babel/eslint-parser":"^7.14.7","@babel/preset-env":"^7.14.7","@babel/register":"^7.14.5","@percy/cli":"^1.0.0-beta.58","@percy/cypress":"^3.1.0","@percy/migrate":"^0.11.0","babel-jest":"^27.0.6","babel-loader":"^8.2.2","concurrently":"^6.2.2","coveralls":"^3.0.2","css-to-string-loader":"^0.1.3","cypress":"8.7.0","documentation":"13.2.0","eslint":"^8.0.0","eslint-config-prettier":"^8.3.0","eslint-plugin-jsdoc":"^37.0.3","eslint-plugin-prettier":"^4.0.0","husky":"^7.0.1","identity-obj-proxy":"^3.0.0","jest":"^27.0.6","jison":"^0.4.18","js-base64":"3.7.2","moment":"^2.23.0","path-browserify":"^1.0.1","prettier":"^2.3.2","prettier-plugin-jsdoc":"^0.3.30","start-server-and-test":"^1.12.6","terser-webpack-plugin":"^5.2.4","webpack":"^5.53.0","webpack-cli":"^4.7.2","webpack-dev-server":"^4.3.0","webpack-node-externals":"^3.0.0"},"files":["dist"],"sideEffects":["**/*.css","**/*.scss"],"husky":{"hooks":{"pre-push":"yarn test"}}}');
module.exports = JSON.parse('{"name":"mermaid","version":"8.13.4","description":"Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.","main":"dist/mermaid.core.js","module":"dist/mermaid.esm.min.mjs","exports":{".":{"require":"./dist/mermaid.core.js","import":"./dist/mermaid.esm.min.mjs"},"./*":"./*"},"keywords":["diagram","markdown","flowchart","sequence diagram","gantt","class diagram","git graph"],"scripts":{"build:development":"webpack --progress --color","build:production":"yarn build:development --mode production --config webpack.config.prod.babel.js","build":"concurrently \\"yarn build:development\\" \\"yarn build:production\\"","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 .","lint:fix":"yarn lint --fix","e2e:depr":"yarn lint && jest e2e --config e2e/jest.config.js","cypress":"percy exec -- cypress run","e2e":"start-server-and-test dev http://localhost:9000/ cypress","e2e-upd":"yarn lint && jest e2e -u --config e2e/jest.config.js","dev":"webpack serve --config webpack.config.e2e.js","test":"yarn lint && jest src/.*","test:watch":"jest --watch src","prepublishOnly":"yarn build && yarn test","prepare":"yarn build"},"repository":{"type":"git","url":"https://github.com/knsv/mermaid"},"author":"Knut Sveidqvist","license":"MIT","standard":{"ignore":["**/parser/*.js","dist/**/*.js","cypress/**/*.js"],"globals":["page"]},"dependencies":{"@braintree/sanitize-url":"^3.1.0","d3":"^7.0.0","dagre":"^0.8.5","dagre-d3":"^0.6.4","dompurify":"2.3.3","graphlib":"^2.1.8","khroma":"^1.4.1","moment-mini":"^2.24.0","stylis":"^4.0.10"},"devDependencies":{"@babel/core":"^7.14.6","@babel/eslint-parser":"^7.14.7","@babel/preset-env":"^7.14.7","@babel/register":"^7.14.5","@percy/cli":"^1.0.0-beta.58","@percy/cypress":"^3.1.0","@percy/migrate":"^0.11.0","babel-jest":"^27.0.6","babel-loader":"^8.2.2","concurrently":"^6.2.2","coveralls":"^3.0.2","css-to-string-loader":"^0.1.3","cypress":"9.0.0","documentation":"13.2.0","eslint":"^8.2.0","eslint-config-prettier":"^8.3.0","eslint-plugin-cypress":"^2.12.1","eslint-plugin-jest":"^25.2.4","eslint-plugin-jsdoc":"^37.0.3","eslint-plugin-prettier":"^4.0.0","husky":"^7.0.1","identity-obj-proxy":"^3.0.0","jest":"^27.0.6","jison":"^0.4.18","js-base64":"3.7.2","moment":"^2.23.0","path-browserify":"^1.0.1","prettier":"^2.3.2","prettier-plugin-jsdoc":"^0.3.30","start-server-and-test":"^1.12.6","terser-webpack-plugin":"^5.2.4","webpack":"^5.53.0","webpack-cli":"^4.7.2","webpack-dev-server":"^4.3.0","webpack-node-externals":"^3.0.0"},"files":["dist"],"sideEffects":["**/*.css","**/*.scss"],"husky":{"hooks":{"pre-push":"yarn test"}}}');
/***/ })

2
dist/mermaid.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -55,6 +55,10 @@
})
}
function escapeHTML(html) {
return html.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll('\'', '&apos;')
}
window.$docsify = {
search: 'auto',
name: 'mermaid',
@ -73,7 +77,7 @@
currentCodeExample++;
colorize.push(currentCodeExample);
resultingHTML += (
'<pre id="code' + currentCodeExample + '">' + code + '</pre>'
'<pre id="code' + currentCodeExample + '">' + escapeHTML(code) + '</pre>'
)
}
@ -100,10 +104,11 @@
})
hook.afterEach(function (html, next) {
next(html);
(async() => {
while (!window.hasOwnProperty("monaco"))
await new Promise(resolve => setTimeout(resolve, 1000));
colorizeEverything(html).then(newHTML => next(newHTML))
colorizeEverything(html).then(newHTML => document.querySelector('article.markdown-section').innerHTML = newHTML)
})();
})
}

View File

@ -1,10 +1,10 @@
const { Generator } = require('jison');
const { validate } = require('schema-utils');
const validate = require('schema-utils');
const schema = require('./parser-options-schema.json');
module.exports = function jisonLoader(source) {
const options = this.getOptions();
validate(schema, options, {
(validate.validate || validate)(schema, options, {
name: 'Jison Loader',
baseDataPath: 'options',
});

View File

@ -4,4 +4,4 @@ module.exports = {
process(sourceText, sourcePath, options) {
return new Generator(sourceText, options.transformerConfig).generate();
},
};
};

View File

@ -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 src",
"lint": "eslint .",
"lint:fix": "yarn lint --fix",
"e2e:depr": "yarn lint && jest e2e --config e2e/jest.config.js",
"cypress": "percy exec -- cypress run",
@ -79,10 +79,12 @@
"concurrently": "^6.2.2",
"coveralls": "^3.0.2",
"css-to-string-loader": "^0.1.3",
"cypress": "8.7.0",
"cypress": "9.0.0",
"documentation": "13.2.0",
"eslint": "^8.0.0",
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-jest": "^25.2.4",
"eslint-plugin-jsdoc": "^37.0.3",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.1",
@ -113,4 +115,4 @@
"pre-push": "yarn test"
}
}
}
}

View File

@ -1,12 +1,11 @@
/* eslint-env jasmine */
import * as configApi from './config';
describe('when working with site config', function() {
describe('when working with site config', function () {
beforeEach(() => {
// Resets the site config to default config
configApi.setSiteConfig({});
});
it('should set site config and config properly', function() {
it('should set site config and config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = configApi.getSiteConfig();
@ -15,18 +14,22 @@ describe('when working with site config', function() {
expect(config_1.bar).toEqual(config_0.bar);
expect(config_1).toEqual(config_2);
});
it('should respect secure keys when applying directives', function() {
let config_0 = { foo: 'bar', bar: 'cant-be-changed', secure: [...configApi.defaultConfig.secure, 'bar'] };
it('should respect secure keys when applying directives', function () {
let config_0 = {
foo: 'bar',
bar: 'cant-be-changed',
secure: [...configApi.defaultConfig.secure, 'bar'],
};
configApi.setSiteConfig(config_0);
const directive = { foo: 'baf', bar: 'should-not-be-allowed'};
const cfg = configApi.updateCurrentConfig(config_0,[directive]);
const directive = { foo: 'baf', bar: 'should-not-be-allowed' };
const cfg = configApi.updateCurrentConfig(config_0, [directive]);
expect(cfg.foo).toEqual(directive.foo);
expect(cfg.bar).toBe(config_0.bar)
expect(cfg.bar).toBe(config_0.bar);
});
it('should set reset config properly', function() {
let config_0 = { foo: 'bar', bar: 0};
it('should set reset config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = { foo: 'baf'};
let config_1 = { foo: 'baf' };
configApi.setConfig(config_1);
let config_2 = configApi.getConfig();
expect(config_2.foo).toEqual(config_1.foo);
@ -36,14 +39,14 @@ describe('when working with site config', function() {
let config_4 = configApi.getSiteConfig();
expect(config_4.foo).toEqual(config_0.foo);
});
it('should set global reset config properly', function() {
let config_0 = { foo: 'bar', bar: 0};
it('should set global reset config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = configApi.getSiteConfig();
expect(config_1.foo).toEqual(config_0.foo);
let config_2 = configApi.getConfig();
expect(config_2.foo).toEqual(config_0.foo);
configApi.setConfig({ foobar: 'bar0' })
configApi.setConfig({ foobar: 'bar0' });
let config_3 = configApi.getConfig();
expect(config_3.foobar).toEqual('bar0');
configApi.reset();

View File

@ -5,61 +5,58 @@ describe('Graphlib decorations', () => {
let node;
beforeEach(function () {
setLogLevel(1);
node = { x:171, y:100, width: 210, height: 184};
node = { x: 171, y: 100, width: 210, height: 184 };
});
describe('intersection', function () {
it('case 1 - intersection on left edge of box', function () {
const o = {x: 31, y: 143.2257070163421};
const i = {x: 99.3359375, y: 100}
const o = { x: 31, y: 143.2257070163421 };
const i = { x: 99.3359375, y: 100 };
const int = intersection(node, o, i);
expect(int.x).toBe(66)
expect(int.y).toBeCloseTo(122.139)
expect(int.x).toBe(66);
expect(int.y).toBeCloseTo(122.139);
});
it('case 2 - intersection on left edge of box', function () {
const o = {x: 310.2578125, y: 169.88002060631462};
const i = {x: 127.96875, y: 100};
const o = { x: 310.2578125, y: 169.88002060631462 };
const i = { x: 127.96875, y: 100 };
const node2 = {
height: 337.5,
width: 184.4609375,
x: 100.23046875,
y: 176.75
}
y: 176.75,
};
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(192.4609375)
expect(int.y).toBeCloseTo(145.15711441743503)
expect(int.x).toBeCloseTo(192.4609375);
expect(int.y).toBeCloseTo(145.15711441743503);
});
it('case 3 - intersection on otop of box outside point greater then inside point', function () {
const o = {x: 157, y: 39};
const i = {x: 104, y: 105};
const o = { x: 157, y: 39 };
const i = { x: 104, y: 105 };
const node2 = {
width: 212,
x: 114,
y: 164,
height: 176
}
height: 176,
};
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(133.71)
expect(int.y).toBeCloseTo(76)
expect(int.x).toBeCloseTo(133.71);
expect(int.y).toBeCloseTo(76);
// expect(int.y).toBeCloseTo(67.833)
});
it('case 4 - intersection on top of box inside point greater then inside point', function () {
const o = {x: 144, y: 38};
const i = {x: 198, y: 105};
const node2 = {
width: 212,
x: 114,
y: 164,
height: 176
}
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(174.626 )
expect(int.y).toBeCloseTo(76)
it('case 4 - intersection on top of box inside point greater then inside point', function () {
const o = { x: 144, y: 38 };
const i = { x: 198, y: 105 };
const node2 = {
width: 212,
x: 114,
y: 164,
height: 176,
};
const int = intersection(node2, o, i);
expect(int.x).toBeCloseTo(174.626);
expect(int.y).toBeCloseTo(76);
// expect(int.y).toBeCloseTo(67.833)
});
});
});
});

View File

@ -1,6 +1,11 @@
import graphlib from 'graphlib';
import dagre from 'dagre';
import { validate, adjustClustersAndEdges, extractDecendants, sortNodesByHierarchy } from './mermaid-graphlib';
import {
validate,
adjustClustersAndEdges,
extractDecendants,
sortNodesByHierarchy,
} from './mermaid-graphlib';
import { setLogLevel, log } from '../logger';
describe('Graphlib decorations', () => {
@ -9,17 +14,17 @@ describe('Graphlib decorations', () => {
setLogLevel(1);
g = new graphlib.Graph({
multigraph: true,
compound: true
compound: true,
});
g.setGraph({
rankdir: 'TB',
nodesep: 10,
ranksep: 10,
marginx: 8,
marginy: 8
marginy: 8,
});
g.setDefaultEdgeLabel(function () {
return {};
return {};
});
});
@ -34,7 +39,7 @@ describe('Graphlib decorations', () => {
end
C1 --> C2
*/
g.setNode('a', { data:1});
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setParent('a', 'C1');
@ -65,7 +70,7 @@ describe('Graphlib decorations', () => {
g.setEdge('C1', 'C2');
adjustClustersAndEdges(g);
log.info(g.edges())
log.info(g.edges());
expect(validate(g)).toBe(true);
});
@ -92,7 +97,7 @@ describe('Graphlib decorations', () => {
g.setEdge('C1', 'c', { name: 'C1-external-link' });
adjustClustersAndEdges(g);
log.info(g.nodes())
log.info(g.nodes());
expect(g.nodes().length).toBe(2);
expect(validate(g)).toBe(true);
});
@ -114,69 +119,69 @@ describe('Graphlib decorations', () => {
// g.setEdge('a', 'b', { name: 'C1-internal-link' });
g.setEdge('C1', 'C2', { name: 'C1-external-link' });
log.info(g.nodes())
log.info(g.nodes());
adjustClustersAndEdges(g);
log.info(g.nodes())
log.info(g.nodes());
expect(g.nodes().length).toBe(2);
expect(validate(g)).toBe(true);
});
it('adjustClustersAndEdges GLB6', function () {
/*
it('adjustClustersAndEdges GLB6', function () {
/*
subgraph C1
a
end
C1 --> b
*/
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('C1', { data: 3 });
g.setParent('a', 'C1');
g.setEdge('C1', 'b', { data: 'link1' }, '1');
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('C1', { data: 3 });
g.setParent('a', 'C1');
g.setEdge('C1', 'b', { data: 'link1' }, '1');
// log.info(g.edges())
adjustClustersAndEdges(g);
log.info(g.edges())
expect(g.nodes()).toEqual(['b', 'C1']);
expect(g.edges().length).toBe(1);
expect(validate(g)).toBe(true);
expect(g.node('C1').clusterNode).toBe(true);
// log.info(g.edges())
adjustClustersAndEdges(g);
log.info(g.edges());
expect(g.nodes()).toEqual(['b', 'C1']);
expect(g.edges().length).toBe(1);
expect(validate(g)).toBe(true);
expect(g.node('C1').clusterNode).toBe(true);
const C1Graph = g.node('C1').graph;
expect(C1Graph.nodes()).toEqual(['a']);
});
it('adjustClustersAndEdges GLB7', function () {
/*
const C1Graph = g.node('C1').graph;
expect(C1Graph.nodes()).toEqual(['a']);
});
it('adjustClustersAndEdges GLB7', function () {
/*
subgraph C1
a
end
C1 --> b
C1 --> c
*/
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setParent('a', 'C1');
g.setNode('C1', { data: 4 });
g.setEdge('C1', 'b', { data: 'link1' }, '1');
g.setEdge('C1', 'c', { data: 'link2' }, '2');
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setParent('a', 'C1');
g.setNode('C1', { data: 4 });
g.setEdge('C1', 'b', { data: 'link1' }, '1');
g.setEdge('C1', 'c', { data: 'link2' }, '2');
log.info(g.node('C1'))
adjustClustersAndEdges(g);
log.info(g.edges())
expect(g.nodes()).toEqual(['b', 'c', 'C1']);
expect(g.nodes().length).toBe(3);
expect(g.edges().length).toBe(2);
log.info(g.node('C1'));
adjustClustersAndEdges(g);
log.info(g.edges());
expect(g.nodes()).toEqual(['b', 'c', 'C1']);
expect(g.nodes().length).toBe(3);
expect(g.edges().length).toBe(2);
expect(g.edges().length).toBe(2);
const edgeData = g.edge(g.edges()[1]);
expect(edgeData.data).toBe('link2');
expect(validate(g)).toBe(true);
expect(g.edges().length).toBe(2);
const edgeData = g.edge(g.edges()[1]);
expect(edgeData.data).toBe('link2');
expect(validate(g)).toBe(true);
const C1Graph = g.node('C1').graph;
expect(C1Graph.nodes()).toEqual(['a']);
});
it('adjustClustersAndEdges GLB8', function () {
/*
const C1Graph = g.node('C1').graph;
expect(C1Graph.nodes()).toEqual(['a']);
});
it('adjustClustersAndEdges GLB8', function () {
/*
subgraph A
a
end
@ -189,32 +194,31 @@ describe('Graphlib decorations', () => {
A --> B
A --> C
*/
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setParent('a', 'A');
g.setParent('b', 'B');
g.setParent('c', 'C');
g.setEdge('A', 'B', { data: 'link1' }, '1');
g.setEdge('A', 'C', { data: 'link2' }, '2');
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setParent('a', 'A');
g.setParent('b', 'B');
g.setParent('c', 'C');
g.setEdge('A', 'B', { data: 'link1' }, '1');
g.setEdge('A', 'C', { data: 'link2' }, '2');
// log.info(g.edges())
adjustClustersAndEdges(g);
expect(g.nodes()).toEqual(['A', 'B', 'C']);
expect(g.edges().length).toBe(2);
// log.info(g.edges())
adjustClustersAndEdges(g);
expect(g.nodes()).toEqual(['A', 'B', 'C']);
expect(g.edges().length).toBe(2);
expect(g.edges().length).toBe(2);
const edgeData = g.edge(g.edges()[1]);
expect(edgeData.data).toBe('link2');
expect(validate(g)).toBe(true);
expect(g.edges().length).toBe(2);
const edgeData = g.edge(g.edges()[1]);
expect(edgeData.data).toBe('link2');
expect(validate(g)).toBe(true);
const CGraph = g.node('C').graph;
expect(CGraph.nodes()).toEqual(['c']);
const CGraph = g.node('C').graph;
expect(CGraph.nodes()).toEqual(['c']);
});
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct data GLB10', function () {
/*
it('adjustClustersAndEdges the extracted graphs shall contain the correct data GLB10', function () {
/*
subgraph C
subgraph D
d
@ -222,29 +226,29 @@ describe('Graphlib decorations', () => {
end
*/
g.setNode('C', { data: 1 });
g.setNode('D', { data: 2 });
g.setNode('d', { data: 3 });
g.setParent('d', 'D');
g.setParent('D', 'C');
g.setNode('C', { data: 1 });
g.setNode('D', { data: 2 });
g.setNode('d', { data: 3 });
g.setParent('d', 'D');
g.setParent('D', 'C');
// log.info('Graph before', g.node('D'))
// log.info('Graph before', graphlib.json.write(g))
adjustClustersAndEdges(g);
// log.info('Graph after', graphlib.json.write(g), g.node('C').graph)
// log.info('Graph before', g.node('D'))
// log.info('Graph before', graphlib.json.write(g))
adjustClustersAndEdges(g);
// log.info('Graph after', graphlib.json.write(g), g.node('C').graph)
const CGraph = g.node('C').graph;
const DGraph = CGraph.node('D').graph;
const CGraph = g.node('C').graph;
const DGraph = CGraph.node('D').graph;
expect(CGraph.nodes()).toEqual(['D']);
expect(DGraph.nodes()).toEqual(['d']);
expect(CGraph.nodes()).toEqual(['D']);
expect(DGraph.nodes()).toEqual(['d']);
expect(g.nodes()).toEqual(['C']);
expect(g.nodes().length).toBe(1);
});
expect(g.nodes()).toEqual(['C']);
expect(g.nodes().length).toBe(1);
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct data GLB11', function () {
/*
it('adjustClustersAndEdges the extracted graphs shall contain the correct data GLB11', function () {
/*
subgraph A
a
end
@ -260,86 +264,86 @@ describe('Graphlib decorations', () => {
A --> C
*/
g.setNode('C', { data: 1 });
g.setNode('D', { data: 2 });
g.setNode('d', { data: 3 });
g.setNode('B', { data: 4 });
g.setNode('b', { data: 5 });
g.setNode('A', { data: 6 });
g.setNode('a', { data: 7 });
g.setParent('a', 'A');
g.setParent('b', 'B');
g.setParent('d', 'D');
g.setParent('D', 'C');
g.setEdge('A', 'B', { data: 'link1' }, '1');
g.setEdge('A', 'C', { data: 'link2' }, '2');
g.setNode('C', { data: 1 });
g.setNode('D', { data: 2 });
g.setNode('d', { data: 3 });
g.setNode('B', { data: 4 });
g.setNode('b', { data: 5 });
g.setNode('A', { data: 6 });
g.setNode('a', { data: 7 });
g.setParent('a', 'A');
g.setParent('b', 'B');
g.setParent('d', 'D');
g.setParent('D', 'C');
g.setEdge('A', 'B', { data: 'link1' }, '1');
g.setEdge('A', 'C', { data: 'link2' }, '2');
log.info('Graph before', g.node('D'))
log.info('Graph before', graphlib.json.write(g))
adjustClustersAndEdges(g);
log.trace('Graph after', graphlib.json.write(g))
expect(g.nodes()).toEqual(['C', 'B', 'A']);
expect(g.nodes().length).toBe(3);
expect(g.edges().length).toBe(2);
log.info('Graph before', g.node('D'));
log.info('Graph before', graphlib.json.write(g));
adjustClustersAndEdges(g);
log.trace('Graph after', graphlib.json.write(g));
expect(g.nodes()).toEqual(['C', 'B', 'A']);
expect(g.nodes().length).toBe(3);
expect(g.edges().length).toBe(2);
const AGraph = g.node('A').graph;
const BGraph = g.node('B').graph;
const CGraph = g.node('C').graph;
// log.info(CGraph.nodes());
const DGraph = CGraph.node('D').graph;
// log.info('DG', CGraph.children('D'));
const AGraph = g.node('A').graph;
const BGraph = g.node('B').graph;
const CGraph = g.node('C').graph;
// log.info(CGraph.nodes());
const DGraph = CGraph.node('D').graph;
// log.info('DG', CGraph.children('D'));
log.info('A', AGraph.nodes());
expect(AGraph.nodes().length).toBe(1);
expect(AGraph.nodes()).toEqual(['a']);
log.trace('Nodes', BGraph.nodes())
expect(BGraph.nodes().length).toBe(1);
expect(BGraph.nodes()).toEqual(['b']);
expect(CGraph.nodes()).toEqual(['D']);
expect(CGraph.nodes().length).toEqual(1);
log.info('A', AGraph.nodes());
expect(AGraph.nodes().length).toBe(1);
expect(AGraph.nodes()).toEqual(['a']);
log.trace('Nodes', BGraph.nodes());
expect(BGraph.nodes().length).toBe(1);
expect(BGraph.nodes()).toEqual(['b']);
expect(CGraph.nodes()).toEqual(['D']);
expect(CGraph.nodes().length).toEqual(1);
expect(AGraph.edges().length).toBe(0);
expect(BGraph.edges().length).toBe(0);
expect(CGraph.edges().length).toBe(0);
expect(DGraph.nodes()).toEqual(['d']);
expect(DGraph.edges().length).toBe(0);
// expect(CGraph.node('D')).toEqual({ data: 2 });
expect(g.edges().length).toBe(2);
expect(AGraph.edges().length).toBe(0);
expect(BGraph.edges().length).toBe(0);
expect(CGraph.edges().length).toBe(0);
expect(DGraph.nodes()).toEqual(['d']);
expect(DGraph.edges().length).toBe(0);
// expect(CGraph.node('D')).toEqual({ data: 2 });
expect(g.edges().length).toBe(2);
// expect(g.edges().length).toBe(2);
// const edgeData = g.edge(g.edges()[1]);
// expect(edgeData.data).toBe('link2');
// expect(validate(g)).toBe(true);
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct links GLB20', function () {
/*
// expect(g.edges().length).toBe(2);
// const edgeData = g.edge(g.edges()[1]);
// expect(edgeData.data).toBe('link2');
// expect(validate(g)).toBe(true);
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct links GLB20', function () {
/*
a --> b
subgraph b [Test]
c --> d -->e
end
*/
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setNode('d', { data: 3 });
g.setNode('e', { data: 3 });
g.setParent('c', 'b');
g.setParent('d', 'b');
g.setParent('e', 'b');
g.setEdge('a', 'b', { data: 'link1' }, '1');
g.setEdge('c', 'd', { data: 'link2' }, '2');
g.setEdge('d', 'e', { data: 'link2' }, '2');
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setNode('d', { data: 3 });
g.setNode('e', { data: 3 });
g.setParent('c', 'b');
g.setParent('d', 'b');
g.setParent('e', 'b');
g.setEdge('a', 'b', { data: 'link1' }, '1');
g.setEdge('c', 'd', { data: 'link2' }, '2');
g.setEdge('d', 'e', { data: 'link2' }, '2');
log.info('Graph before', graphlib.json.write(g))
adjustClustersAndEdges(g);
const bGraph = g.node('b').graph;
// log.trace('Graph after', graphlib.json.write(g))
log.info('Graph after', graphlib.json.write(bGraph));
expect(bGraph.nodes().length).toBe(3);
expect(bGraph.edges().length).toBe(2);
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct links GLB21', function () {
/*
log.info('Graph before', graphlib.json.write(g));
adjustClustersAndEdges(g);
const bGraph = g.node('b').graph;
// log.trace('Graph after', graphlib.json.write(g))
log.info('Graph after', graphlib.json.write(bGraph));
expect(bGraph.nodes().length).toBe(3);
expect(bGraph.edges().length).toBe(2);
});
it('adjustClustersAndEdges the extracted graphs shall contain the correct links GLB21', function () {
/*
state a {
state b {
state c {
@ -348,28 +352,27 @@ describe('Graphlib decorations', () => {
}
}
*/
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setNode('e', { data: 3 });
g.setParent('b', 'a');
g.setParent('c', 'b');
g.setParent('e', 'c');
g.setNode('a', { data: 1 });
g.setNode('b', { data: 2 });
g.setNode('c', { data: 3 });
g.setNode('e', { data: 3 });
g.setParent('b', 'a');
g.setParent('c', 'b');
g.setParent('e', 'c');
log.info('Graph before', graphlib.json.write(g))
adjustClustersAndEdges(g);
const aGraph = g.node('a').graph;
const bGraph = aGraph.node('b').graph;
log.info('Graph after', graphlib.json.write(aGraph));
const cGraph = bGraph.node('c').graph;
// log.trace('Graph after', graphlib.json.write(g))
expect(aGraph.nodes().length).toBe(1);
expect(bGraph.nodes().length).toBe(1);
expect(cGraph.nodes().length).toBe(1);
expect(bGraph.edges().length).toBe(0);
log.info('Graph before', graphlib.json.write(g));
adjustClustersAndEdges(g);
const aGraph = g.node('a').graph;
const bGraph = aGraph.node('b').graph;
log.info('Graph after', graphlib.json.write(aGraph));
const cGraph = bGraph.node('c').graph;
// log.trace('Graph after', graphlib.json.write(g))
expect(aGraph.nodes().length).toBe(1);
expect(bGraph.nodes().length).toBe(1);
expect(cGraph.nodes().length).toBe(1);
expect(bGraph.edges().length).toBe(0);
});
});
});
it('adjustClustersAndEdges should handle nesting GLB77', function () {
/*
flowchart TB
@ -382,10 +385,12 @@ flowchart TB
end
*/
const exportedGraph = JSON.parse('{"options":{"directed":true,"multigraph":true,"compound":true},"nodes":[{"v":"A","value":{"labelStyle":"","shape":"rect","labelText":"A","rx":0,"ry":0,"class":"default","style":"","id":"A","width":500,"type":"group","padding":15}},{"v":"B","value":{"labelStyle":"","shape":"rect","labelText":"B","rx":0,"ry":0,"class":"default","style":"","id":"B","width":500,"type":"group","padding":15},"parent":"A"},{"v":"b","value":{"labelStyle":"","shape":"rect","labelText":"b","rx":0,"ry":0,"class":"default","style":"","id":"b","padding":15},"parent":"A"},{"v":"c","value":{"labelStyle":"","shape":"rect","labelText":"c","rx":0,"ry":0,"class":"default","style":"","id":"c","padding":15},"parent":"B"},{"v":"a","value":{"labelStyle":"","shape":"rect","labelText":"a","rx":0,"ry":0,"class":"default","style":"","id":"a","padding":15},"parent":"A"}],"edges":[{"v":"b","w":"B","name":"1","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-b-B","classes":"flowchart-link LS-b LE-B"}},{"v":"a","w":"c","name":"2","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-a-c","classes":"flowchart-link LS-a LE-c"}}],"value":{"rankdir":"TB","nodesep":50,"ranksep":50,"marginx":8,"marginy":8}}');
const gr = graphlib.json.read(exportedGraph)
const exportedGraph = JSON.parse(
'{"options":{"directed":true,"multigraph":true,"compound":true},"nodes":[{"v":"A","value":{"labelStyle":"","shape":"rect","labelText":"A","rx":0,"ry":0,"class":"default","style":"","id":"A","width":500,"type":"group","padding":15}},{"v":"B","value":{"labelStyle":"","shape":"rect","labelText":"B","rx":0,"ry":0,"class":"default","style":"","id":"B","width":500,"type":"group","padding":15},"parent":"A"},{"v":"b","value":{"labelStyle":"","shape":"rect","labelText":"b","rx":0,"ry":0,"class":"default","style":"","id":"b","padding":15},"parent":"A"},{"v":"c","value":{"labelStyle":"","shape":"rect","labelText":"c","rx":0,"ry":0,"class":"default","style":"","id":"c","padding":15},"parent":"B"},{"v":"a","value":{"labelStyle":"","shape":"rect","labelText":"a","rx":0,"ry":0,"class":"default","style":"","id":"a","padding":15},"parent":"A"}],"edges":[{"v":"b","w":"B","name":"1","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-b-B","classes":"flowchart-link LS-b LE-B"}},{"v":"a","w":"c","name":"2","value":{"minlen":1,"arrowhead":"normal","arrowTypeStart":"arrow_open","arrowTypeEnd":"arrow_point","thickness":"normal","pattern":"solid","style":"fill:none","labelStyle":"","arrowheadStyle":"fill: #333","labelpos":"c","labelType":"text","label":"","id":"L-a-c","classes":"flowchart-link LS-a LE-c"}}],"value":{"rankdir":"TB","nodesep":50,"ranksep":50,"marginx":8,"marginy":8}}'
);
const gr = graphlib.json.read(exportedGraph);
log.info('Graph before', graphlib.json.write(gr))
log.info('Graph before', graphlib.json.write(gr));
adjustClustersAndEdges(gr);
const aGraph = gr.node('A').graph;
const bGraph = aGraph.node('B').graph;
@ -394,7 +399,6 @@ flowchart TB
expect(aGraph.parent('c')).toBe('B');
expect(aGraph.parent('B')).toBe(undefined);
});
});
describe('extractDecendants', function () {
let g;
@ -402,14 +406,14 @@ describe('extractDecendants', function () {
setLogLevel(1);
g = new graphlib.Graph({
multigraph: true,
compound: true
compound: true,
});
g.setGraph({
rankdir: 'TB',
nodesep: 10,
ranksep: 10,
marginx: 8,
marginy: 8
marginy: 8,
});
g.setDefaultEdgeLabel(function () {
return {};
@ -439,9 +443,9 @@ describe('extractDecendants', function () {
g.setEdge('A', 'C', { data: 'link2' }, '2');
// log.info(g.edges())
const d1 = extractDecendants('A',g)
const d2 = extractDecendants('B',g)
const d3 = extractDecendants('C',g)
const d1 = extractDecendants('A', g);
const d2 = extractDecendants('B', g);
const d3 = extractDecendants('C', g);
expect(d1).toEqual(['a']);
expect(d2).toEqual(['b']);
@ -454,14 +458,14 @@ describe('sortNodesByHierarchy', function () {
setLogLevel(1);
g = new graphlib.Graph({
multigraph: true,
compound: true
compound: true,
});
g.setGraph({
rankdir: 'TB',
nodesep: 10,
ranksep: 10,
marginx: 8,
marginy: 8
marginy: 8,
});
g.setDefaultEdgeLabel(function () {
return {};
@ -484,7 +488,7 @@ describe('sortNodesByHierarchy', function () {
g.setEdge('a', 'b', '1');
expect(sortNodesByHierarchy(g)).toEqual(['a', 'A', 'B', 'b']);
});
it('it should sort proper en nodes are in correct order', function () {
it('it should sort proper en nodes are in correct order', function () {
/*
a -->b
subgraph B

View File

@ -1,15 +1,14 @@
/* eslint-env jasmine */
import { parser } from './parser/classDiagram';
import classDb from './classDb';
describe('class diagram, ', function() {
describe('when parsing data from a classDiagram it', function() {
beforeEach(function() {
describe('class diagram, ', function () {
describe('when parsing data from a classDiagram it', function () {
beforeEach(function () {
parser.yy = classDb;
parser.yy.clear();
});
it('should be possible to apply a css class to a class directly', function() {
it('should be possible to apply a css class to a class directly', function () {
const str = 'classDiagram\n' + 'class Class01:::exClass';
parser.parse(str);
@ -32,7 +31,7 @@ describe('class diagram, ', function() {
expect(testClass.cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a css class to a class with relations', function() {
it('should be possible to apply a css class to a class with relations', function () {
const str = 'classDiagram\n' + 'Class01 <|-- Class02\ncssClass "Class01" exClass';
parser.parse(str);
@ -40,7 +39,7 @@ describe('class diagram, ', function() {
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a cssClass to a class', function() {
it('should be possible to apply a cssClass to a class', function () {
const str = 'classDiagram\n' + 'class Class01\n cssClass "Class01" exClass';
parser.parse(str);
@ -48,8 +47,9 @@ describe('class diagram, ', function() {
expect(parser.yy.getClass('Class01').cssClasses[0]).toBe('exClass');
});
it('should be possible to apply a cssClass to a comma separated list of classes', function() {
const str = 'classDiagram\n' + 'class Class01\n class Class02\n cssClass "Class01,Class02" exClass';
it('should be possible to apply a cssClass to a comma separated list of classes', function () {
const str =
'classDiagram\n' + 'class Class01\n class Class02\n cssClass "Class01,Class02" exClass';
parser.parse(str);

View File

@ -1,4 +1,3 @@
/* eslint-env jasmine */
import { parser } from './parser/classDiagram';
import classDb from './classDb';
@ -10,10 +9,8 @@ describe('class diagram, ', function () {
parser.yy = classDb;
});
it('should handle backquoted class names', function() {
const str =
'classDiagram\n' +
'class `Car`';
it('should handle backquoted class names', function () {
const str = 'classDiagram\n' + 'class `Car`';
parser.parse(str);
});
@ -64,7 +61,7 @@ describe('class diagram, ', function () {
parser.parse(str);
});
it('should handle visibility for methods and members', function() {
it('should handle visibility for methods and members', function () {
const str =
'classDiagram\n' +
'class TestClass\n' +
@ -78,7 +75,7 @@ describe('class diagram, ', function () {
parser.parse(str);
});
it('should handle generic class', function() {
it('should handle generic class', function () {
const str =
'classDiagram\n' +
'class Car~T~\n' +
@ -89,7 +86,7 @@ describe('class diagram, ', function () {
parser.parse(str);
});
it('should handle generic class with a literal name', function() {
it('should handle generic class with a literal name', function () {
const str =
'classDiagram\n' +
'class `Car`~T~\n' +
@ -100,7 +97,7 @@ describe('class diagram, ', function () {
parser.parse(str);
});
it('should break when another `{`is encountered before closing the first one while defining generic class with brackets', function() {
it('should break when another `{`is encountered before closing the first one while defining generic class with brackets', function () {
const str =
'classDiagram\n' +
'class Dummy_Class~T~ {\n' +
@ -113,17 +110,17 @@ describe('class diagram, ', function () {
' flightNumber : Integer\n' +
' departureTime : Date\n' +
'}';
let testPased =false;
try{
let testPased = false;
try {
parser.parse(str);
}catch (error){
} catch (error) {
console.log(error.name);
testPased = true;
}
expect(testPased).toBe(true);
});
it('should break when EOF is encountered before closing the first `{` while defining generic class with brackets', function() {
it('should break when EOF is encountered before closing the first `{` while defining generic class with brackets', function () {
const str =
'classDiagram\n' +
'class Dummy_Class~T~ {\n' +
@ -132,17 +129,17 @@ describe('class diagram, ', function () {
'}\n' +
'\n' +
'class Dummy_Class {\n';
let testPased =false;
try{
let testPased = false;
try {
parser.parse(str);
}catch (error){
} catch (error) {
console.log(error.name);
testPased = true;
}
expect(testPased).toBe(true);
});
it('should handle generic class with brackets', function() {
it('should handle generic class with brackets', function () {
const str =
'classDiagram\n' +
'class Dummy_Class~T~ {\n' +
@ -155,10 +152,10 @@ describe('class diagram, ', function () {
' departureTime : Date\n' +
'}';
parser.parse(str);
parser.parse(str);
});
it('should handle generic class with brackets and a literal name', function() {
it('should handle generic class with brackets and a literal name', function () {
const str =
'classDiagram\n' +
'class `Dummy_Class`~T~ {\n' +
@ -171,10 +168,10 @@ describe('class diagram, ', function () {
' departureTime : Date\n' +
'}';
parser.parse(str);
parser.parse(str);
});
it('should handle class definitions', function() {
it('should handle class definitions', function () {
const str =
'classDiagram\n' +
'class Car\n' +
@ -290,8 +287,7 @@ describe('class diagram, ', function () {
});
it('should handle comments at the start', function () {
const str =
`%% Comment
const str = `%% Comment
classDiagram
class Class1 {
int : test
@ -303,8 +299,7 @@ describe('class diagram, ', function () {
});
it('should handle comments at the end', function () {
const str =
`classDiagram
const str = `classDiagram
class Class1 {
int : test
string : foo
@ -319,8 +314,7 @@ foo()
});
it('should handle comments at the end no trailing newline', function () {
const str =
`classDiagram
const str = `classDiagram
class Class1 {
int : test
string : foo
@ -333,8 +327,7 @@ foo()
});
it('should handle a comment with multiple line feeds', function () {
const str =
`classDiagram
const str = `classDiagram
%% Comment
@ -350,8 +343,7 @@ foo()
});
it('should handle a comment with mermaid class diagram code in them', function () {
const str =
`classDiagram
const str = `classDiagram
%% Comment Class01 <|-- Class02
class Class1 {
int : test
@ -393,19 +385,19 @@ foo()
});
it('should handle click statement with click and href link', function () {
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 href "google.com" ';
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 href "google.com" ';
parser.parse(str);
});
parser.parse(str);
});
it('should handle click statement with link and tooltip', function () {
const str =
@ -422,21 +414,20 @@ foo()
parser.parse(str);
});
it('should handle click statement with click and href link and tooltip', function () {
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 href "google.com" "A Tooltip" ';
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 href "google.com" "A Tooltip" ';
parser.parse(str);
});
parser.parse(str);
});
it('should handle click statement with callback', function () {
const str =
@ -454,19 +445,19 @@ foo()
});
it('should handle click statement with click and call callback', function () {
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 call functionCall() ';
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 call functionCall() ';
parser.parse(str);
});
parser.parse(str);
});
it('should handle click statement with callback and tooltip', function () {
const str =
@ -484,19 +475,19 @@ foo()
});
it('should handle click statement with click and call callback and tooltip', function () {
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 call functionCall() "A Tooltip" ';
const str =
'classDiagram\n' +
'class Class1 {\n' +
'%% Comment Class01 <|-- Class02\n' +
'int : test\n' +
'string : foo\n' +
'test()\n' +
'foo()\n' +
'}\n' +
'click Class01 call functionCall() "A Tooltip" ';
parser.parse(str);
});
parser.parse(str);
});
it('should handle dashed relation definition of different types and directions', function () {
const str =
@ -522,12 +513,12 @@ foo()
it('should handle generic types in members in class with brackets', function () {
const str =
'classDiagram\n' +
'class Car {\n' +
'List~Wheel~ wheels\n' +
'classDiagram\n' +
'class Car {\n' +
'List~Wheel~ wheels\n' +
'setWheels(List~Wheel~ wheels)\n' +
'+getWheels() List~Wheel~\n' +
'}';
'}';
parser.parse(str);
});
@ -747,51 +738,71 @@ foo()
});
it('should associate link and css appropriately', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'link Class1 "google.com"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank');//('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
it('should associate click and href link and css appropriately', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com"';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'link Class1 "google.com"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank');//('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.link).toBe('about:blank'); //('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
it('should associate click and href link and css appropriately', function () {
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 href "google.com"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank'); //('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
it('should associate link with tooltip', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'link Class1 "google.com" "A tooltip"';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'link Class1 "google.com" "A tooltip"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank');//('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.link).toBe('about:blank'); //('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.tooltip).toBe('A tooltip');
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
it('should associate click and href link with tooltip', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com" "A tooltip"';
parser.parse(str);
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 href "google.com" "A tooltip"';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank');//('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.tooltip).toBe('A tooltip');
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
const testClass = parser.yy.getClass('Class1');
expect(testClass.link).toBe('about:blank'); //('google.com'); security needs to be set to 'loose' for this to work right
expect(testClass.tooltip).toBe('A tooltip');
expect(testClass.cssClasses.length).toBe(1);
expect(testClass.cssClasses[0]).toBe('clickable');
});
it('should associate click and href link with tooltip and target appropriately', function () {
spyOn(classDb, 'setLink');
spyOn(classDb, 'setTooltip');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com" "A tooltip" _self';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 href "google.com" "A tooltip" _self';
parser.parse(str);
expect(classDb.setLink).toHaveBeenCalledWith('Class1', 'google.com', '_self');
@ -800,7 +811,11 @@ foo()
it('should associate click and href link appropriately', function () {
spyOn(classDb, 'setLink');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com"';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 href "google.com"';
parser.parse(str);
expect(classDb.setLink).toHaveBeenCalledWith('Class1', 'google.com');
@ -808,7 +823,11 @@ foo()
it('should associate click and href link with target appropriately', function () {
spyOn(classDb, 'setLink');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 href "google.com" _self';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 href "google.com" _self';
parser.parse(str);
expect(classDb.setLink).toHaveBeenCalledWith('Class1', 'google.com', '_self');
@ -817,7 +836,11 @@ foo()
it('should associate link appropriately', function () {
spyOn(classDb, 'setLink');
spyOn(classDb, 'setTooltip');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'link Class1 "google.com" "A tooltip" _self';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'link Class1 "google.com" "A tooltip" _self';
parser.parse(str);
expect(classDb.setLink).toHaveBeenCalledWith('Class1', 'google.com', '_self');
@ -826,16 +849,23 @@ foo()
it('should associate callback appropriately', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'callback Class1 "functionCall"';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'callback Class1 "functionCall"';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall');
});
it('should associate click and call callback appropriately', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 call functionCall()';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 call functionCall()';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall');
@ -843,16 +873,28 @@ foo()
it('should associate callback appropriately with an arbitrary number of args', function () {
spyOn(classDb, 'setClickEvent');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 call functionCall("test0", test1, test2)';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 call functionCall("test0", test1, test2)';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall','"test0", test1, test2');
expect(classDb.setClickEvent).toHaveBeenCalledWith(
'Class1',
'functionCall',
'"test0", test1, test2'
);
});
it('should associate callback with tooltip', function () {
spyOn(classDb, 'setClickEvent');
spyOn(classDb, 'setTooltip');
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : someMethod()\n' + 'click Class1 call functionCall() "A tooltip"';
const str =
'classDiagram\n' +
'class Class1\n' +
'Class1 : someMethod()\n' +
'click Class1 call functionCall() "A tooltip"';
parser.parse(str);
expect(classDb.setClickEvent).toHaveBeenCalledWith('Class1', 'functionCall');

View File

@ -1,12 +1,11 @@
/* eslint-env jasmine */
const fs = require("fs");
const fs = require('fs');
import { LALRGenerator } from "jison";
import { LALRGenerator } from 'jison';
describe('class diagram grammar', function () {
it("should introduce no new conflicts", function() {
const file = require.resolve("./parser/classDiagram.jison");
const grammarSource = fs.readFileSync(file, "utf8");
it('should introduce no new conflicts', function () {
const file = require.resolve('./parser/classDiagram.jison');
const grammarSource = fs.readFileSync(file, 'utf8');
const grammarParser = new LALRGenerator(grammarSource, {});
expect(grammarParser.conflicts < 16).toBe(true);
});

View File

@ -1,4 +1,3 @@
/* eslint-env jasmine */
import svgDraw from './svgDraw';
describe('class member Renderer, ', function () {
@ -78,7 +77,7 @@ describe('class member Renderer, ', function () {
it('should handle simple method declaration with parameters', function () {
const str = 'foo(int id)';
let actual = svgDraw.parseMember(str);
expect(actual.displayText).toBe('foo(int id)');
expect(actual.cssStyle).toBe('');
});
@ -86,7 +85,7 @@ describe('class member Renderer, ', function () {
it('should handle simple method declaration with multiple parameters', function () {
const str = 'foo(int id, object thing)';
let actual = svgDraw.parseMember(str);
expect(actual.displayText).toBe('foo(int id, object thing)');
expect(actual.cssStyle).toBe('');
});

View File

@ -1,7 +1,7 @@
import { removeScript } from './common';
describe('when securityLevel is antiscript, all script must be removed', function() {
it('should remove all script block, script inline.', function() {
describe('when securityLevel is antiscript, all script must be removed', function () {
it('should remove all script block, script inline.', function () {
const labelString = `1
Act1: Hello 1<script src="http://abc.com/script1.js"></script>1
<b>Act2</b>:
@ -10,17 +10,17 @@ describe('when securityLevel is antiscript, all script must be removed', functio
</script>1
1`;
const result = removeScript(labelString);
const hasScript = (result.indexOf("script") >= 0);
const result = removeScript(labelString);
const hasScript = result.indexOf('script') >= 0;
expect(hasScript).toEqual(false);
const exactlyString = `1
const exactlyString = `1
Act1: Hello 11
<b>Act2</b>:
11
1`;
const isEqual = (result == exactlyString);
const isEqual = result == exactlyString;
expect(isEqual).toEqual(true);
});
});

View File

@ -3,11 +3,10 @@ import erDb from '../erDb';
import erDiagram from './erDiagram';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing ER diagram it...', function () {
beforeEach(function () {
erDiagram.parser.yy = erDb;
erDiagram.parser.yy.clear();
@ -78,7 +77,9 @@ describe('when parsing ER diagram it...', function () {
const attribute2 = 'string author';
const attribute3 = 'float price';
erDiagram.parser.parse(`erDiagram\n${entity} {\n${attribute1}\n${attribute2}\n${attribute3}\n}`);
erDiagram.parser.parse(
`erDiagram\n${entity} {\n${attribute1}\n${attribute2}\n${attribute3}\n}`
);
const entities = erDb.getEntities();
expect(entities[entity].attributes.length).toBe(3);
});
@ -89,7 +90,9 @@ describe('when parsing ER diagram it...', function () {
const attribute2 = 'string author';
const attribute3 = 'float price';
erDiagram.parser.parse(`erDiagram\n${entity} {\n${attribute1}\n}\n${entity} {\n${attribute2}\n${attribute3}\n}`);
erDiagram.parser.parse(
`erDiagram\n${entity} {\n${attribute1}\n}\n${entity} {\n${attribute2}\n${attribute3}\n}`
);
const entities = erDb.getEntities();
expect(entities[entity].attributes.length).toBe(3);
});
@ -196,7 +199,6 @@ describe('when parsing ER diagram it...', function () {
/* TODO */
});
it('should handle only-one-to-one-or-more relationships', function () {
erDiagram.parser.parse('erDiagram\nA ||--|{ B : has');
const rels = erDb.getRelationships();
@ -215,7 +217,6 @@ describe('when parsing ER diagram it...', function () {
expect(rels.length).toBe(1);
expect(rels[0].relSpec.cardA).toBe(erDb.Cardinality.ZERO_OR_MORE);
expect(rels[0].relSpec.cardB).toBe(erDb.Cardinality.ONLY_ONE);
});
it('should handle zero-or-one-to-zero-or-more relationships', function () {

View File

@ -1,16 +1,18 @@
import { addToRender } from './flowChartShapes';
describe('flowchart shapes', function() {
describe('flowchart shapes', function () {
// rect-based shapes
[
['stadium', useWidth, useHeight]
].forEach(function([shapeType, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly positioned rect element`, function() {
[['stadium', useWidth, useHeight]].forEach(function ([shapeType, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly positioned rect element`, function () {
const mockRender = MockRender();
const mockSvg = MockSvg();
addToRender(mockRender);
[[100, 100], [123, 45], [71, 300]].forEach(function([width, height]) {
[
[100, 100],
[123, 45],
[71, 300],
].forEach(function ([width, height]) {
const shape = mockRender.shapes()[shapeType](mockSvg, { width, height }, {});
const w = width + height / 4;
const h = height;
@ -24,15 +26,17 @@ describe('flowchart shapes', function() {
});
// path-based shapes
[
['cylinder', useWidth, useHeight]
].forEach(function([shapeType, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly positioned path element`, function() {
[['cylinder', useWidth, useHeight]].forEach(function ([shapeType, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly positioned path element`, function () {
const mockRender = MockRender();
const mockSvg = MockSvg();
addToRender(mockRender);
[[100, 100], [123, 45], [71, 300]].forEach(function([width, height]) {
[
[100, 100],
[123, 45],
[71, 300],
].forEach(function ([width, height]) {
const shape = mockRender.shapes()[shapeType](mockSvg, { width, height }, {});
expect(shape.__tag).toEqual('path');
expect(shape.__attrs).toHaveProperty('d');
@ -45,20 +49,20 @@ describe('flowchart shapes', function() {
[
'question',
4,
function(w, h) {
function (w, h) {
return (w + h) * 0.9;
},
function(w, h) {
function (w, h) {
return (w + h) * 0.9;
}
},
],
[
'hexagon',
6,
function(w, h) {
function (w, h) {
return w + h / 2;
},
useHeight
useHeight,
],
['rect_left_inv_arrow', 5, useWidth, useHeight],
['rect_right_inv_arrow', 5, useWidth, useHeight],
@ -67,13 +71,17 @@ describe('flowchart shapes', function() {
['trapezoid', 4, useWidth, useHeight],
['inv_trapezoid', 4, useWidth, useHeight],
['subroutine', 10, useWidth, useHeight],
].forEach(function([shapeType, expectedPointCount, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly translated polygon element`, function() {
].forEach(function ([shapeType, expectedPointCount, getW, getH]) {
it(`should add a ${shapeType} shape that renders a properly translated polygon element`, function () {
const mockRender = MockRender();
const mockSvg = MockSvg();
addToRender(mockRender);
[[100, 100], [123, 45], [71, 300]].forEach(function([width, height]) {
[
[100, 100],
[123, 45],
[71, 300],
].forEach(function ([width, height]) {
const shape = mockRender.shapes()[shapeType](mockSvg, { width, height }, {});
const dx = -getW(width, height) / 2;
const dy = getH(width, height) / 2;
@ -91,7 +99,7 @@ function MockRender() {
return {
shapes() {
return shapes;
}
},
};
}
@ -111,7 +119,7 @@ function MockSvg(tag, ...args) {
get __attrs() {
return attributes;
},
insert: function(tag, ...args) {
insert: function (tag, ...args) {
const child = MockSvg(tag, ...args);
children.push(child);
return child;
@ -119,10 +127,14 @@ function MockSvg(tag, ...args) {
attr(name, value) {
this.__attrs[name] = value;
return this;
}
},
};
}
/**
* @param w
* @param h
*/
function useWidth(w, h) {
return w;
}

View File

@ -2,12 +2,12 @@ import flowDb from './flowDb';
describe('flow db subgraphs', () => {
let subgraphs;
beforeEach( ()=>{
beforeEach(() => {
subgraphs = [
{nodes:['a', 'b', 'c', 'e']},
{nodes:['f', 'g', 'h']},
{nodes:['i', 'j']},
{nodes:['k']},
{ nodes: ['a', 'b', 'c', 'e'] },
{ nodes: ['f', 'g', 'h'] },
{ nodes: ['i', 'j'] },
{ nodes: ['k'] },
];
});
describe('exist', () => {
@ -23,22 +23,21 @@ describe('flow db subgraphs', () => {
});
});
describe('makeUniq', () => {
it('should remove ids from sungraph that already exists in another subgraph even if it gets empty', () => {
const subgraph = flowDb.makeUniq({nodes:['i', 'j']}, subgraphs);
describe('makeUniq', () => {
it('should remove ids from sungraph that already exists in another subgraph even if it gets empty', () => {
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j'] }, subgraphs);
expect(subgraph.nodes).toEqual([]);
});
it('should remove ids from sungraph that already exists in another subgraph', () => {
const subgraph = flowDb.makeUniq({nodes:['i', 'j', 'o']}, subgraphs);
expect(subgraph.nodes).toEqual(['o']);
});
it('should not remove ids from subgraph if they are unique', () => {
const subgraph = flowDb.makeUniq({nodes:['q', 'r', 's']}, subgraphs);
expect(subgraph.nodes).toEqual(['q', 'r', 's']);
});
expect(subgraph.nodes).toEqual([]);
});
});
it('should remove ids from sungraph that already exists in another subgraph', () => {
const subgraph = flowDb.makeUniq({ nodes: ['i', 'j', 'o'] }, subgraphs);
expect(subgraph.nodes).toEqual(['o']);
});
it('should not remove ids from subgraph if they are unique', () => {
const subgraph = flowDb.makeUniq({ nodes: ['q', 'r', 's'] }, subgraphs);
expect(subgraph.nodes).toEqual(['q', 'r', 's']);
});
});
});

View File

@ -3,12 +3,12 @@ import { setConfig } from '../../config';
setConfig({
flowchart: {
htmlLabels: false
}
htmlLabels: false,
},
});
describe('the flowchart renderer', function() {
describe('when adding vertices to a graph', function() {
describe('the flowchart renderer', function () {
describe('when adding vertices to a graph', function () {
[
['round', 'rect', 5],
['square', 'rect'],
@ -25,14 +25,14 @@ describe('the flowchart renderer', function() {
['stadium', 'stadium'],
['subroutine', 'subroutine'],
['cylinder', 'cylinder'],
['group', 'rect']
].forEach(function([type, expectedShape, expectedRadios = 0]) {
it(`should add the correct shaped node to the graph for vertex type ${type}`, function() {
['group', 'rect'],
].forEach(function ([type, expectedShape, expectedRadios = 0]) {
it(`should add the correct shaped node to the graph for vertex type ${type}`, function () {
const addedNodes = [];
const mockG = {
setNode: function(id, object) {
setNode: function (id, object) {
addedNodes.push([id, object]);
}
},
};
addVertices(
{
@ -41,8 +41,8 @@ describe('the flowchart renderer', function() {
id: 'my-node-id',
classes: [],
styles: [],
text: 'my vertex text'
}
text: 'my vertex text',
},
},
mockG,
'svg-id'
@ -57,18 +57,15 @@ describe('the flowchart renderer', function() {
});
});
[
'Multi<br>Line',
'Multi<br/>Line',
'Multi<br />Line',
'Multi<br\t/>Line'
].forEach(function(labelText) {
it('should handle multiline texts with different line breaks', function() {
['Multi<br>Line', 'Multi<br/>Line', 'Multi<br />Line', 'Multi<br\t/>Line'].forEach(function (
labelText
) {
it('should handle multiline texts with different line breaks', function () {
const addedNodes = [];
const mockG = {
setNode: function(id, object) {
setNode: function (id, object) {
addedNodes.push([id, object]);
}
},
};
addVertices(
{
@ -77,8 +74,8 @@ describe('the flowchart renderer', function() {
id: 'my-node-id',
classes: [],
styles: [],
text: 'Multi<br>Line'
}
text: 'Multi<br>Line',
},
},
mockG,
'svg-id'
@ -98,14 +95,18 @@ describe('the flowchart renderer', function() {
[['fill:#fff'], 'fill:#fff;', ''],
[['color:#ccc'], '', 'color:#ccc;'],
[['fill:#fff', 'color:#ccc'], 'fill:#fff;', 'color:#ccc;'],
[['fill:#fff', 'color:#ccc', 'text-align:center'], 'fill:#fff;', 'color:#ccc;text-align:center;']
].forEach(function([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function() {
[
['fill:#fff', 'color:#ccc', 'text-align:center'],
'fill:#fff;',
'color:#ccc;text-align:center;',
],
].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function () {
const addedNodes = [];
const mockG = {
setNode: function(id, object) {
setNode: function (id, object) {
addedNodes.push([id, object]);
}
},
};
addVertices(
{
@ -114,8 +115,8 @@ describe('the flowchart renderer', function() {
id: 'my-node-id',
classes: [],
styles: style,
text: 'my vertex text'
}
text: 'my vertex text',
},
},
mockG,
'svg-id'
@ -129,12 +130,12 @@ describe('the flowchart renderer', function() {
});
});
it(`should add default class to all nodes which do not have another class assigned`, function() {
it(`should add default class to all nodes which do not have another class assigned`, function () {
const addedNodes = [];
const mockG = {
setNode: function(id, object) {
setNode: function (id, object) {
addedNodes.push([id, object]);
}
},
};
addVertices(
{
@ -143,15 +144,15 @@ describe('the flowchart renderer', function() {
id: 'defaultNode',
classes: [],
styles: [],
text: 'my vertex text'
text: 'my vertex text',
},
v2: {
type: 'rect',
id: 'myNode',
classes: ['myClass'],
styles: [],
text: 'my vertex text'
}
text: 'my vertex text',
},
},
mockG,
'svg-id'
@ -164,13 +165,13 @@ describe('the flowchart renderer', function() {
});
});
describe('when adding edges to a graph', function() {
it('should handle multiline texts and set centered label position', function() {
describe('when adding edges to a graph', function () {
it('should handle multiline texts and set centered label position', function () {
const addedEdges = [];
const mockG = {
setEdge: function(s, e, data, c) {
setEdge: function (s, e, data, c) {
addedEdges.push(data);
}
},
};
addEdges(
[
@ -181,13 +182,13 @@ describe('the flowchart renderer', function() {
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br>Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br/>Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br />Line' },
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' }
{ style: ['stroke:DarkGray', 'stroke-width:2px'], text: 'Multi<br\t/>Line' },
],
mockG,
'svg-id'
);
addedEdges.forEach(function(edge) {
addedEdges.forEach(function (edge) {
expect(edge).toHaveProperty('label', 'Multi\nLine');
expect(edge).toHaveProperty('labelpos', 'c');
});
@ -197,22 +198,20 @@ describe('the flowchart renderer', function() {
[['stroke:DarkGray'], 'stroke:DarkGray;', ''],
[['color:red'], '', 'fill:red;'],
[['stroke:DarkGray', 'color:red'], 'stroke:DarkGray;', 'fill:red;'],
[['stroke:DarkGray', 'color:red', 'stroke-width:2px'], 'stroke:DarkGray;stroke-width:2px;', 'fill:red;']
].forEach(function([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function() {
[
['stroke:DarkGray', 'color:red', 'stroke-width:2px'],
'stroke:DarkGray;stroke-width:2px;',
'fill:red;',
],
].forEach(function ([style, expectedStyle, expectedLabelStyle]) {
it(`should add the styles to style and/or labelStyle for style ${style}`, function () {
const addedEdges = [];
const mockG = {
setEdge: function(s, e, data, c) {
setEdge: function (s, e, data, c) {
addedEdges.push(data);
}
},
};
addEdges(
[
{ style: style, text: 'styling' }
],
mockG,
'svg-id'
);
addEdges([{ style: style, text: 'styling' }], mockG, 'svg-id');
expect(addedEdges).toHaveLength(1);
expect(addedEdges[0]).toHaveProperty('style', expectedStyle);

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Arrows] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('should handle a nodes and edges', function() {
it('should handle a nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA-->B;');
const vert = flow.parser.yy.getVertices();
@ -29,7 +29,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it("should handle angle bracket ' > ' as direction LR", function() {
it("should handle angle bracket ' > ' as direction LR", function () {
const res = flow.parser.parse('graph >;A-->B;');
const vert = flow.parser.yy.getVertices();
@ -49,7 +49,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it("should handle angle bracket ' < ' as direction RL", function() {
it("should handle angle bracket ' < ' as direction RL", function () {
const res = flow.parser.parse('graph <;A-->B;');
const vert = flow.parser.yy.getVertices();
@ -69,7 +69,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it("should handle caret ' ^ ' as direction BT", function() {
it("should handle caret ' ^ ' as direction BT", function () {
const res = flow.parser.parse('graph ^;A-->B;');
const vert = flow.parser.yy.getVertices();
@ -90,7 +90,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it("should handle lower-case 'v' as direction TB", function() {
it("should handle lower-case 'v' as direction TB", function () {
const res = flow.parser.parse('graph v;A-->B;');
const vert = flow.parser.yy.getVertices();
@ -110,7 +110,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle a nodes and edges and a space between link and node', function() {
it('should handle a nodes and edges and a space between link and node', function () {
const res = flow.parser.parse('graph TD;A --> B;');
const vert = flow.parser.yy.getVertices();
@ -127,7 +127,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function() {
it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function () {
const res = flow.parser.parse('graph TD\nA --> B\n style e red');
const vert = flow.parser.yy.getVertices();
@ -144,7 +144,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle statements ending without semicolon', function() {
it('should handle statements ending without semicolon', function () {
const res = flow.parser.parse('graph TD\nA-->B\nB-->C');
const vert = flow.parser.yy.getVertices();
@ -161,9 +161,9 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
describe('it should handle multi directional arrows', function() {
describe('point', function() {
it('should handle double edged nodes and edges', function() {
describe('it should handle multi directional arrows', function () {
describe('point', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA<-->B;');
const vert = flow.parser.yy.getVertices();
@ -180,7 +180,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text', function() {
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA<-- text -->B;');
const vert = flow.parser.yy.getVertices();
@ -197,7 +197,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on thick arrows', function() {
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA<==>B;');
const vert = flow.parser.yy.getVertices();
@ -214,7 +214,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on thick arrows', function() {
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA<== text ==>B;');
const vert = flow.parser.yy.getVertices();
@ -231,7 +231,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on dotted arrows', function() {
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA<-.->B;');
const vert = flow.parser.yy.getVertices();
@ -248,7 +248,7 @@ describe('[Arrows] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on dotted arrows', function() {
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA<-. text .->B;');
const vert = flow.parser.yy.getVertices();

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Comments] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('should handle comments', function() {
it('should handle comments', function () {
const res = flow.parser.parse('graph TD;\n%% Comment\n A-->B;');
const vert = flow.parser.yy.getVertices();
@ -27,7 +27,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle comments at the start', function() {
it('should handle comments at the start', function () {
const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;');
const vert = flow.parser.yy.getVertices();
@ -42,7 +42,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle comments at the end', function() {
it('should handle comments at the end', function () {
const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the end\n');
const vert = flow.parser.yy.getVertices();
@ -57,7 +57,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle comments at the end no trailing newline', function() {
it('should handle comments at the end no trailing newline', function () {
const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento');
const vert = flow.parser.yy.getVertices();
@ -72,7 +72,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle comments at the end many trailing newlines', function() {
it('should handle comments at the end many trailing newlines', function () {
const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento\n\n\n');
const vert = flow.parser.yy.getVertices();
@ -87,7 +87,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle no trailing newlines', function() {
it('should handle no trailing newlines', function () {
const res = flow.parser.parse('graph TD;\n A-->B');
const vert = flow.parser.yy.getVertices();
@ -102,7 +102,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle many trailing newlines', function() {
it('should handle many trailing newlines', function () {
const res = flow.parser.parse('graph TD;\n A-->B\n\n');
const vert = flow.parser.yy.getVertices();
@ -117,7 +117,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle a comment with blank rows in-between', function() {
it('should handle a comment with blank rows in-between', function () {
const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;');
const vert = flow.parser.yy.getVertices();
@ -132,7 +132,7 @@ describe('[Comments] when parsing', () => {
expect(edges[0].text).toBe('');
});
it('should handle a comment with mermaid flowchart code in them', function() {
it('should handle a comment with mermaid flowchart code in them', function () {
const res = flow.parser.parse(
'graph TD;\n\n\n %% Test od>Odd shape]-->|Two line<br>edge comment|ro;\n A-->B;'
);

View File

@ -8,18 +8,17 @@ import { setConfig } from '../../../config';
// const clean = DOMPurify.sanitize(dirty);
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing directions', function() {
beforeEach(function() {
describe('when parsing directions', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
it('should use default direction from top level', function() {
it('should use default direction from top level', function () {
const res = flow.parser.parse(`flowchart TB
subgraph A
a --> b
@ -34,7 +33,7 @@ describe('when parsing directions', function() {
expect(subgraph.id).toBe('A');
expect(subgraph.dir).toBe(undefined);
});
it('should handle a subgraph with a direction', function() {
it('should handle a subgraph with a direction', function () {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction BT
@ -50,7 +49,7 @@ describe('when parsing directions', function() {
expect(subgraph.id).toBe('A');
expect(subgraph.dir).toBe('BT');
});
it('should use the last defined direction', function() {
it('should use the last defined direction', function () {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction BT
@ -68,7 +67,7 @@ describe('when parsing directions', function() {
expect(subgraph.dir).toBe('RL');
});
it('should handle nested subgraphs 1', function() {
it('should handle nested subgraphs 1', function () {
const res = flow.parser.parse(`flowchart TB
subgraph A
direction RL
@ -84,8 +83,8 @@ describe('when parsing directions', function() {
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(2);
const subgraphA = filter(subgraphs,o => o.id === 'A')[0];
const subgraphB = filter(subgraphs,o => o.id === 'B')[0];
const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0];
const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0];
expect(subgraphB.nodes[0]).toBe('c');
expect(subgraphB.dir).toBe('LR');
@ -95,5 +94,4 @@ describe('when parsing directions', function() {
expect(subgraphA.nodes).not.toContain('c');
expect(subgraphA.dir).toBe('RL');
});
});

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Edges] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('should handle open ended edges', function() {
it('should handle open ended edges', function () {
const res = flow.parser.parse('graph TD;A---B;');
const vert = flow.parser.yy.getVertices();
@ -21,7 +21,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].type).toBe('arrow_open');
});
it('should handle cross ended edges', function() {
it('should handle cross ended edges', function () {
const res = flow.parser.parse('graph TD;A--xB;');
const vert = flow.parser.yy.getVertices();
@ -30,7 +30,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle open ended edges', function() {
it('should handle open ended edges', function () {
const res = flow.parser.parse('graph TD;A--oB;');
const vert = flow.parser.yy.getVertices();
@ -39,8 +39,8 @@ describe('[Edges] when parsing', () => {
expect(edges[0].type).toBe('arrow_circle');
});
describe('cross', function() {
it('should handle double edged nodes and edges', function() {
describe('cross', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA x--x B;');
const vert = flow.parser.yy.getVertices();
@ -57,7 +57,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text', function() {
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA x-- text --x B;');
const vert = flow.parser.yy.getVertices();
@ -74,7 +74,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on thick arrows', function() {
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA x==x B;');
const vert = flow.parser.yy.getVertices();
@ -91,7 +91,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on thick arrows', function() {
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA x== text ==x B;');
const vert = flow.parser.yy.getVertices();
@ -108,7 +108,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on dotted arrows', function() {
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA x-.-x B;');
const vert = flow.parser.yy.getVertices();
@ -125,7 +125,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on dotted arrows', function() {
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA x-. text .-x B;');
const vert = flow.parser.yy.getVertices();
@ -143,8 +143,8 @@ describe('[Edges] when parsing', () => {
});
});
describe('circle', function() {
it('should handle double edged nodes and edges', function() {
describe('circle', function () {
it('should handle double edged nodes and edges', function () {
const res = flow.parser.parse('graph TD;\nA o--o B;');
const vert = flow.parser.yy.getVertices();
@ -161,7 +161,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text', function() {
it('should handle double edged nodes with text', function () {
const res = flow.parser.parse('graph TD;\nA o-- text --o B;');
const vert = flow.parser.yy.getVertices();
@ -178,7 +178,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on thick arrows', function() {
it('should handle double edged nodes and edges on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA o==o B;');
const vert = flow.parser.yy.getVertices();
@ -195,7 +195,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on thick arrows', function() {
it('should handle double edged nodes with text on thick arrows', function () {
const res = flow.parser.parse('graph TD;\nA o== text ==o B;');
const vert = flow.parser.yy.getVertices();
@ -212,7 +212,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes and edges on dotted arrows', function() {
it('should handle double edged nodes and edges on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA o-.-o B;');
const vert = flow.parser.yy.getVertices();
@ -229,7 +229,7 @@ describe('[Edges] when parsing', () => {
expect(edges[0].length).toBe(1);
});
it('should handle double edged nodes with text on dotted arrows', function() {
it('should handle double edged nodes with text on dotted arrows', function () {
const res = flow.parser.parse('graph TD;\nA o-. text .-o B;');
const vert = flow.parser.yy.getVertices();
@ -247,7 +247,7 @@ describe('[Edges] when parsing', () => {
});
});
it('should handle multiple edges', function() {
it('should handle multiple edges', function () {
const res = flow.parser.parse(
'graph TD;A---|This is the 123 s text|B;\nA---|This is the second edge|B;'
);
@ -271,9 +271,9 @@ describe('[Edges] when parsing', () => {
expect(edges[1].length).toBe(1);
});
describe('edge length', function() {
describe('edge length', function () {
for (let length = 1; length <= 3; ++length) {
it(`should handle normal edges with length ${length}`, function() {
it(`should handle normal edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -${'-'.repeat(length)}- B;`);
const vert = flow.parser.yy.getVertices();
@ -292,7 +292,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle normal labelled edges with length ${length}`, function() {
it(`should handle normal labelled edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -- Label -${'-'.repeat(length)}- B;`);
const vert = flow.parser.yy.getVertices();
@ -311,7 +311,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle normal edges with arrows with length ${length}`, function() {
it(`should handle normal edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -${'-'.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -330,7 +330,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle normal labelled edges with arrows with length ${length}`, function() {
it(`should handle normal labelled edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -- Label -${'-'.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -349,7 +349,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle normal edges with double arrows with length ${length}`, function() {
it(`should handle normal edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <-${'-'.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -368,7 +368,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle normal labelled edges with double arrows with length ${length}`, function() {
it(`should handle normal labelled edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <-- Label -${'-'.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -387,7 +387,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick edges with length ${length}`, function() {
it(`should handle thick edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA =${'='.repeat(length)}= B;`);
const vert = flow.parser.yy.getVertices();
@ -406,7 +406,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick labelled edges with length ${length}`, function() {
it(`should handle thick labelled edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA == Label =${'='.repeat(length)}= B;`);
const vert = flow.parser.yy.getVertices();
@ -425,7 +425,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick edges with arrows with length ${length}`, function() {
it(`should handle thick edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA =${'='.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -444,7 +444,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick labelled edges with arrows with length ${length}`, function() {
it(`should handle thick labelled edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA == Label =${'='.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -463,7 +463,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick edges with double arrows with length ${length}`, function() {
it(`should handle thick edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <=${'='.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -482,7 +482,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle thick labelled edges with double arrows with length ${length}`, function() {
it(`should handle thick labelled edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <== Label =${'='.repeat(length)}> B;`);
const vert = flow.parser.yy.getVertices();
@ -501,7 +501,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted edges with length ${length}`, function() {
it(`should handle dotted edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -${'.'.repeat(length)}- B;`);
const vert = flow.parser.yy.getVertices();
@ -520,7 +520,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted labelled edges with length ${length}`, function() {
it(`should handle dotted labelled edges with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -. Label ${'.'.repeat(length)}- B;`);
const vert = flow.parser.yy.getVertices();
@ -539,7 +539,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted edges with arrows with length ${length}`, function() {
it(`should handle dotted edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -${'.'.repeat(length)}-> B;`);
const vert = flow.parser.yy.getVertices();
@ -558,7 +558,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted labelled edges with arrows with length ${length}`, function() {
it(`should handle dotted labelled edges with arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA -. Label ${'.'.repeat(length)}-> B;`);
const vert = flow.parser.yy.getVertices();
@ -577,7 +577,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted edges with double arrows with length ${length}`, function() {
it(`should handle dotted edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <-${'.'.repeat(length)}-> B;`);
const vert = flow.parser.yy.getVertices();
@ -596,7 +596,7 @@ describe('[Edges] when parsing', () => {
}
for (let length = 1; length <= 3; ++length) {
it(`should handle dotted edges with double arrows with length ${length}`, function() {
it(`should handle dotted edges with double arrows with length ${length}`, function () {
const res = flow.parser.parse(`graph TD;\nA <-. Label ${'.'.repeat(length)}-> B;`);
const vert = flow.parser.yy.getVertices();

File diff suppressed because one or more lines are too long

View File

@ -5,16 +5,16 @@ import { setConfig } from '../../../config';
const spyOn = jest.spyOn;
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Interactions] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('it should be possible to use click to a callback', function() {
it('it should be possible to use click to a callback', function () {
spyOn(flowDb, 'setClickEvent');
const res = flow.parser.parse('graph TD\nA-->B\nclick A callback');
@ -24,7 +24,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback');
});
it('it should be possible to use click to a click and call callback', function() {
it('it should be possible to use click to a click and call callback', function () {
spyOn(flowDb, 'setClickEvent');
const res = flow.parser.parse('graph TD\nA-->B\nclick A call callback()');
@ -34,7 +34,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback');
});
it('it should be possible to use click to a callback with toolip', function() {
it('it should be possible to use click to a callback with toolip', function () {
spyOn(flowDb, 'setClickEvent');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A callback "tooltip"');
@ -43,10 +43,10 @@ describe('[Interactions] when parsing', () => {
const edges = flow.parser.yy.getEdges();
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
it('it should be possible to use click to a click and call callback with toolip', function() {
it('it should be possible to use click to a click and call callback with toolip', function () {
spyOn(flowDb, 'setClickEvent');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A call callback() "tooltip"');
@ -55,20 +55,20 @@ describe('[Interactions] when parsing', () => {
const edges = flow.parser.yy.getEdges();
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
it('it should be possible to use click to a callback with an arbitrary number of args', function() {
spyOn(flowDb, 'setClickEvent');
const res = flow.parser.parse('graph TD\nA-->B\nclick A call callback("test0", test1, test2)');
it('it should be possible to use click to a callback with an arbitrary number of args', function () {
spyOn(flowDb, 'setClickEvent');
const res = flow.parser.parse('graph TD\nA-->B\nclick A call callback("test0", test1, test2)');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback','"test0", test1, test2');
});
expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', '"test0", test1, test2');
});
it('should handle interaction - click to a link', function() {
it('should handle interaction - click to a link', function () {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html"');
@ -78,7 +78,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html');
});
it('should handle interaction - click to a click and href link', function() {
it('should handle interaction - click to a click and href link', function () {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A href "click.html"');
@ -88,7 +88,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html');
});
it('should handle interaction - click to a link with tooltip', function() {
it('should handle interaction - click to a link with tooltip', function () {
spyOn(flowDb, 'setLink');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip"');
@ -97,10 +97,10 @@ describe('[Interactions] when parsing', () => {
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
it('should handle interaction - click to a click and href link with tooltip', function() {
it('should handle interaction - click to a click and href link with tooltip', function () {
spyOn(flowDb, 'setLink');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A href "click.html" "tooltip"');
@ -109,10 +109,10 @@ describe('[Interactions] when parsing', () => {
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
it('should handle interaction - click to a link with target', function() {
it('should handle interaction - click to a link with target', function () {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" _blank');
@ -122,7 +122,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', '_blank');
});
it('should handle interaction - click to a click and href link with target', function() {
it('should handle interaction - click to a click and href link with target', function () {
spyOn(flowDb, 'setLink');
const res = flow.parser.parse('graph TD\nA-->B\nclick A href "click.html" _blank');
@ -132,7 +132,7 @@ describe('[Interactions] when parsing', () => {
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', '_blank');
});
it('should handle interaction - click to a link with tooltip and target', function() {
it('should handle interaction - click to a link with tooltip and target', function () {
spyOn(flowDb, 'setLink');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip" _blank');
@ -141,19 +141,18 @@ describe('[Interactions] when parsing', () => {
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', '_blank');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
it('should handle interaction - click to a click and href link with tooltip and target', function() {
spyOn(flowDb, 'setLink');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A href "click.html" "tooltip" _blank');
it('should handle interaction - click to a click and href link with tooltip and target', function () {
spyOn(flowDb, 'setLink');
spyOn(flowDb, 'setTooltip');
const res = flow.parser.parse('graph TD\nA-->B\nclick A href "click.html" "tooltip" _blank');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', '_blank');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A','tooltip');
});
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(flowDb.setLink).toHaveBeenCalledWith('A', 'click.html', '_blank');
expect(flowDb.setTooltip).toHaveBeenCalledWith('A', 'tooltip');
});
});

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Lines] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('should handle line interpolation default definitions', function() {
it('should handle line interpolation default definitions', function () {
const res = flow.parser.parse('graph TD\n' + 'A-->B\n' + 'linkStyle default interpolate basis');
const vert = flow.parser.yy.getVertices();
@ -21,7 +21,7 @@ describe('[Lines] when parsing', () => {
expect(edges.defaultInterpolate).toBe('basis');
});
it('should handle line interpolation numbered definitions', function() {
it('should handle line interpolation numbered definitions', function () {
const res = flow.parser.parse(
'graph TD\n' +
'A-->B\n' +
@ -37,7 +37,7 @@ describe('[Lines] when parsing', () => {
expect(edges[1].interpolate).toBe('cardinal');
});
it('should handle line interpolation multi-numbered definitions', function() {
it('should handle line interpolation multi-numbered definitions', function () {
const res = flow.parser.parse(
'graph TD\n' + 'A-->B\n' + 'A-->C\n' + 'linkStyle 0,1 interpolate basis'
);
@ -49,7 +49,7 @@ describe('[Lines] when parsing', () => {
expect(edges[1].interpolate).toBe('basis');
});
it('should handle line interpolation default with style', function() {
it('should handle line interpolation default with style', function () {
const res = flow.parser.parse(
'graph TD\n' + 'A-->B\n' + 'linkStyle default interpolate basis stroke-width:1px;'
);
@ -60,7 +60,7 @@ describe('[Lines] when parsing', () => {
expect(edges.defaultInterpolate).toBe('basis');
});
it('should handle line interpolation numbered with style', function() {
it('should handle line interpolation numbered with style', function () {
const res = flow.parser.parse(
'graph TD\n' +
'A-->B\n' +
@ -76,7 +76,7 @@ describe('[Lines] when parsing', () => {
expect(edges[1].interpolate).toBe('cardinal');
});
it('should handle line interpolation multi-numbered with style', function() {
it('should handle line interpolation multi-numbered with style', function () {
const res = flow.parser.parse(
'graph TD\n' + 'A-->B\n' + 'A-->C\n' + 'linkStyle 0,1 interpolate basis stroke-width:1px;'
);
@ -88,8 +88,8 @@ describe('[Lines] when parsing', () => {
expect(edges[1].interpolate).toBe('basis');
});
describe('it should handle new line type notation', function() {
it('it should handle regular lines', function() {
describe('it should handle new line type notation', function () {
it('it should handle regular lines', function () {
const res = flow.parser.parse('graph TD;A-->B;');
const vert = flow.parser.yy.getVertices();
@ -98,7 +98,7 @@ describe('[Lines] when parsing', () => {
expect(edges[0].stroke).toBe('normal');
});
it('it should handle dotted lines', function() {
it('it should handle dotted lines', function () {
const res = flow.parser.parse('graph TD;A-.->B;');
const vert = flow.parser.yy.getVertices();
@ -107,7 +107,7 @@ describe('[Lines] when parsing', () => {
expect(edges[0].stroke).toBe('dotted');
});
it('it should handle dotted lines', function() {
it('it should handle dotted lines', function () {
const res = flow.parser.parse('graph TD;A==>B;');
const vert = flow.parser.yy.getVertices();

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Singlenodes] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('should handle a single node', function() {
it('should handle a single node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;A;');
@ -22,7 +22,7 @@ describe('[Singlenodes] when parsing', () => {
expect(edges.length).toBe(0);
expect(vert['A'].styles.length).toBe(0);
});
it('should handle a single node with white space after it (SN1)', function() {
it('should handle a single node with white space after it (SN1)', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;A ;');
@ -33,7 +33,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['A'].styles.length).toBe(0);
});
it('should handle a single square node', function() {
it('should handle a single square node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a[A];');
@ -45,7 +45,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('square');
});
it('should handle a single round square node', function() {
it('should handle a single round square node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a[A];');
@ -57,7 +57,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('square');
});
it('should handle a single circle node', function() {
it('should handle a single circle node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a((A));');
@ -68,7 +68,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('circle');
});
it('should handle a single round node', function() {
it('should handle a single round node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a(A);');
@ -79,7 +79,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('round');
});
it('should handle a single odd node', function() {
it('should handle a single odd node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a>A];');
@ -90,7 +90,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('odd');
});
it('should handle a single diamond node', function() {
it('should handle a single diamond node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a{A};');
@ -101,7 +101,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('diamond');
});
it('should handle a single diamond node with whitespace after it', function() {
it('should handle a single diamond node with whitespace after it', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a{A} ;');
@ -112,7 +112,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('diamond');
});
it('should handle a single diamond node with html in it (SN3)', function() {
it('should handle a single diamond node with html in it (SN3)', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a{A <br> end};');
@ -124,7 +124,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].text).toBe('A <br> end');
});
it('should handle a single hexagon node', function() {
it('should handle a single hexagon node', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a{{A}};');
@ -135,7 +135,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].type).toBe('hexagon');
});
it('should handle a single hexagon node with html in it', function() {
it('should handle a single hexagon node with html in it', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a{{A <br> end}};');
@ -147,7 +147,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].text).toBe('A <br> end');
});
it('should handle a single round node with html in it', function() {
it('should handle a single round node with html in it', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;a(A <br> end);');
@ -159,7 +159,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['a'].text).toBe('A <br> end');
});
it('should handle a single node with alphanumerics starting on a char', function() {
it('should handle a single node with alphanumerics starting on a char', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;id1;');
@ -170,7 +170,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['id1'].styles.length).toBe(0);
});
it('should handle a single node with a single digit', function() {
it('should handle a single node with a single digit', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;1;');
@ -181,7 +181,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['1'].text).toBe('1');
});
it('should handle a single node with a single digit in a subgraph', function() {
it('should handle a single node with a single digit in a subgraph', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;subgraph "hello";1;end;');
@ -193,7 +193,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['1'].text).toBe('1');
});
it('should handle a single node with alphanumerics starting on a num', function() {
it('should handle a single node with alphanumerics starting on a num', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;1id;');
@ -204,7 +204,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['1id'].styles.length).toBe(0);
});
it('should handle a single node with alphanumerics containing a minus sign', function() {
it('should handle a single node with alphanumerics containing a minus sign', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;i-d;');
@ -215,7 +215,7 @@ describe('[Singlenodes] when parsing', () => {
expect(vert['i-d'].styles.length).toBe(0);
});
it('should handle a single node with alphanumerics containing a underscore sign', function() {
it('should handle a single node with alphanumerics containing a underscore sign', function () {
// Silly but syntactically correct
const res = flow.parser.parse('graph TD;i_d;');

View File

@ -3,18 +3,18 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Style] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
// log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
it('should handle styles for vertices', function() {
it('should handle styles for vertices', function () {
const res = flow.parser.parse('graph TD;style Q background:#fff;');
const vert = flow.parser.yy.getVertices();
@ -27,7 +27,7 @@ describe('[Style] when parsing', () => {
});
// log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
it('should handle styles for edges', function() {
it('should handle styles for edges', function () {
const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;');
const edges = flow.parser.yy.getEdges();
@ -35,7 +35,7 @@ describe('[Style] when parsing', () => {
expect(edges.length).toBe(1);
});
it('should handle multiple styles for a vortex', function() {
it('should handle multiple styles for a vortex', function () {
const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;');
const vert = flow.parser.yy.getVertices();
@ -46,7 +46,7 @@ describe('[Style] when parsing', () => {
expect(vert['R'].styles[1]).toBe('border:1px solid red');
});
it('should handle multiple styles in a graph', function() {
it('should handle multiple styles in a graph', function () {
const res = flow.parser.parse(
'graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'
);
@ -61,7 +61,7 @@ describe('[Style] when parsing', () => {
expect(vert['T'].styles[1]).toBe('border:1px solid red');
});
it('should handle styles and graph definitions in a graph', function() {
it('should handle styles and graph definitions in a graph', function () {
const res = flow.parser.parse(
'graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'
);
@ -76,7 +76,7 @@ describe('[Style] when parsing', () => {
expect(vert['T'].styles[1]).toBe('border:1px solid red');
});
it('should handle styles and graph definitions in a graph', function() {
it('should handle styles and graph definitions in a graph', function () {
const res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;');
// const res = flow.parser.parse('graph TD;style T background: #bbb;');
@ -87,8 +87,10 @@ describe('[Style] when parsing', () => {
expect(vert['T'].styles[1]).toBe('border:1px solid red');
});
it('should keep node label text (if already defined) when a style is applied', function() {
const res = flow.parser.parse('graph TD;A(( ));B((Test));C;style A background:#fff;style D border:1px solid red;');
it('should keep node label text (if already defined) when a style is applied', function () {
const res = flow.parser.parse(
'graph TD;A(( ));B((Test));C;style A background:#fff;style D border:1px solid red;'
);
const vert = flow.parser.yy.getVertices();
@ -98,7 +100,7 @@ describe('[Style] when parsing', () => {
expect(vert['D'].text).toBe('D');
});
it('should be possible to declare a class', function() {
it('should be possible to declare a class', function () {
const res = flow.parser.parse(
'graph TD;classDef exClass background:#bbb,border:1px solid red;'
);
@ -111,7 +113,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to declare a class with a dot in the style', function() {
it('should be possible to declare a class with a dot in the style', function () {
const res = flow.parser.parse(
'graph TD;classDef exClass background:#bbb,border:1.5px solid red;'
);
@ -123,7 +125,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[0]).toBe('background:#bbb');
expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red');
});
it('should be possible to declare a class with a space in the style', function() {
it('should be possible to declare a class with a space in the style', function () {
const res = flow.parser.parse(
'graph TD;classDef exClass background: #bbb,border:1.5px solid red;'
);
@ -135,7 +137,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[0]).toBe('background: #bbb');
expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red');
});
it('should be possible to apply a class to a vertex', function() {
it('should be possible to apply a class to a vertex', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -151,7 +153,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[0]).toBe('background:#bbb');
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a vertex with an id containing _', function() {
it('should be possible to apply a class to a vertex with an id containing _', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -167,7 +169,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[0]).toBe('background:#bbb');
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a vertex directly', function() {
it('should be possible to apply a class to a vertex directly', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -184,7 +186,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a vertex directly : usecase A[text].class ', function() {
it('should be possible to apply a class to a vertex directly : usecase A[text].class ', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -201,7 +203,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a vertex directly : usecase A[text].class-->B[test2] ', function() {
it('should be possible to apply a class to a vertex directly : usecase A[text].class-->B[test2] ', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -218,7 +220,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a vertex directly 2', function() {
it('should be possible to apply a class to a vertex directly 2', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -234,7 +236,7 @@ describe('[Style] when parsing', () => {
expect(classes['exClass'].styles[0]).toBe('background:#bbb');
expect(classes['exClass'].styles[1]).toBe('border:1px solid red');
});
it('should be possible to apply a class to a comma separated list of vertices', function() {
it('should be possible to apply a class to a comma separated list of vertices', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -254,7 +256,7 @@ describe('[Style] when parsing', () => {
expect(vertices['b'].classes[0]).toBe('exClass');
});
it('should handle style definitions with more then 1 digit in a row', function() {
it('should handle style definitions with more then 1 digit in a row', function () {
const res = flow.parser.parse(
'graph TD\n' +
'A-->B1\n' +
@ -277,7 +279,7 @@ describe('[Style] when parsing', () => {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle multi-numbered style definitions with more then 1 digit in a row', function() {
it('should handle multi-numbered style definitions with more then 1 digit in a row', function () {
const res = flow.parser.parse(
'graph TD\n' +
'A-->B1\n' +
@ -301,7 +303,7 @@ describe('[Style] when parsing', () => {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle classDefs with style in classes', function() {
it('should handle classDefs with style in classes', function () {
const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;');
const vert = flow.parser.yy.getVertices();
@ -310,7 +312,7 @@ describe('[Style] when parsing', () => {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle classDefs with % in classes', function() {
it('should handle classDefs with % in classes', function () {
const res = flow.parser.parse(
'graph TD\nA-->B\nclassDef exClass fill:#f96,stroke:#333,stroke-width:4px,font-size:50%,font-style:bold;'
);

View File

@ -3,17 +3,17 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('[Text] when parsing', () => {
beforeEach(function() {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
describe('it should handle text on edges', function() {
it('it should handle text without space', function() {
describe('it should handle text on edges', function () {
it('it should handle text without space', function () {
const res = flow.parser.parse('graph TD;A--x|textNoSpace|B;');
const vert = flow.parser.yy.getVertices();
@ -22,7 +22,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle with space', function() {
it('should handle with space', function () {
const res = flow.parser.parse('graph TD;A--x|text including space|B;');
const vert = flow.parser.yy.getVertices();
@ -31,7 +31,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('it should handle text with /', function() {
it('it should handle text with /', function () {
const res = flow.parser.parse('graph TD;A--x|text with / should work|B;');
const vert = flow.parser.yy.getVertices();
@ -40,7 +40,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text with / should work');
});
it('it should handle space and space between vertices and link', function() {
it('it should handle space and space between vertices and link', function () {
const res = flow.parser.parse('graph TD;A --x|textNoSpace| B;');
const vert = flow.parser.yy.getVertices();
@ -49,7 +49,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle space and CAPS', function() {
it('should handle space and CAPS', function () {
const res = flow.parser.parse('graph TD;A--x|text including CAPS space|B;');
const vert = flow.parser.yy.getVertices();
@ -58,7 +58,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle space and dir', function() {
it('should handle space and dir', function () {
const res = flow.parser.parse('graph TD;A--x|text including URL space|B;');
const vert = flow.parser.yy.getVertices();
@ -68,7 +68,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including URL space');
});
it('should handle space and send', function() {
it('should handle space and send', function () {
const res = flow.parser.parse('graph TD;A--text including URL space and send-->B;');
const vert = flow.parser.yy.getVertices();
@ -77,7 +77,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_point');
expect(edges[0].text).toBe('text including URL space and send');
});
it('should handle space and send', function() {
it('should handle space and send', function () {
const res = flow.parser.parse('graph TD;A-- text including URL space and send -->B;');
const vert = flow.parser.yy.getVertices();
@ -87,7 +87,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including URL space and send');
});
it('should handle space and dir (TD)', function() {
it('should handle space and dir (TD)', function () {
const res = flow.parser.parse('graph TD;A--x|text including R TD space|B;');
const vert = flow.parser.yy.getVertices();
@ -96,7 +96,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].text).toBe('text including R TD space');
});
it('should handle `', function() {
it('should handle `', function () {
const res = flow.parser.parse('graph TD;A--x|text including `|B;');
const vert = flow.parser.yy.getVertices();
@ -105,7 +105,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].text).toBe('text including `');
});
it('should handle v in node ids only v', function() {
it('should handle v in node ids only v', function () {
// only v
const res = flow.parser.parse('graph TD;A--xv(my text);');
@ -115,7 +115,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(vert['v'].text).toBe('my text');
});
it('should handle v in node ids v at end', function() {
it('should handle v in node ids v at end', function () {
// v at end
const res = flow.parser.parse('graph TD;A--xcsv(my text);');
@ -125,7 +125,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(vert['csv'].text).toBe('my text');
});
it('should handle v in node ids v in middle', function() {
it('should handle v in node ids v in middle', function () {
// v in middle
const res = flow.parser.parse('graph TD;A--xava(my text);');
@ -135,7 +135,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(vert['ava'].text).toBe('my text');
});
it('should handle v in node ids, v at start', function() {
it('should handle v in node ids, v at start', function () {
// v at start
const res = flow.parser.parse('graph TD;A--xva(my text);');
@ -145,7 +145,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(vert['va'].text).toBe('my text');
});
it('should handle keywords', function() {
it('should handle keywords', function () {
const res = flow.parser.parse('graph TD;A--x|text including graph space|B;');
const vert = flow.parser.yy.getVertices();
@ -153,19 +153,19 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including graph space');
});
it('should handle keywords', function() {
it('should handle keywords', function () {
const res = flow.parser.parse('graph TD;V-->a[v]');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert['a'].text).toBe('v');
});
it('should handle keywords', function() {
it('should handle keywords', function () {
const res = flow.parser.parse('graph TD;V-->a[v]');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
expect(vert['a'].text).toBe('v');
});
it('should handle quoted text', function() {
it('should handle quoted text', function () {
const res = flow.parser.parse('graph TD;V-- "test string()" -->a[v]');
const vert = flow.parser.yy.getVertices();
const edges = flow.parser.yy.getEdges();
@ -174,7 +174,7 @@ describe('[Text] when parsing', () => {
});
describe('it should handle text on lines', () => {
it('it should handle normal text on lines', function() {
it('it should handle normal text on lines', function () {
const res = flow.parser.parse('graph TD;A-- test text with == -->B;');
const vert = flow.parser.yy.getVertices();
@ -182,7 +182,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].stroke).toBe('normal');
});
it('it should handle dotted text on lines (TD3)', function() {
it('it should handle dotted text on lines (TD3)', function () {
const res = flow.parser.parse('graph TD;A-. test text with == .->B;');
const vert = flow.parser.yy.getVertices();
@ -190,7 +190,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].stroke).toBe('dotted');
});
it('it should handle thick text on lines', function() {
it('it should handle thick text on lines', function () {
const res = flow.parser.parse('graph TD;A== test text with - ==>B;');
const vert = flow.parser.yy.getVertices();
@ -200,8 +200,8 @@ describe('[Text] when parsing', () => {
});
});
describe('it should handle text on edges using the new notation', function() {
it('it should handle text without space', function() {
describe('it should handle text on edges using the new notation', function () {
it('it should handle text without space', function () {
const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;');
const vert = flow.parser.yy.getVertices();
@ -210,7 +210,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('it should handle text with multiple leading space', function() {
it('it should handle text with multiple leading space', function () {
const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;');
const vert = flow.parser.yy.getVertices();
@ -219,7 +219,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle with space', function() {
it('should handle with space', function () {
const res = flow.parser.parse('graph TD;A-- text including space --xB;');
const vert = flow.parser.yy.getVertices();
@ -228,7 +228,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('it should handle text with /', function() {
it('it should handle text with /', function () {
const res = flow.parser.parse('graph TD;A -- text with / should work --x B;');
const vert = flow.parser.yy.getVertices();
@ -237,7 +237,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text with / should work');
});
it('it should handle space and space between vertices and link', function() {
it('it should handle space and space between vertices and link', function () {
const res = flow.parser.parse('graph TD;A -- textNoSpace --x B;');
const vert = flow.parser.yy.getVertices();
@ -246,7 +246,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle space and CAPS', function() {
it('should handle space and CAPS', function () {
const res = flow.parser.parse('graph TD;A-- text including CAPS space --xB;');
const vert = flow.parser.yy.getVertices();
@ -255,7 +255,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
});
it('should handle space and dir', function() {
it('should handle space and dir', function () {
const res = flow.parser.parse('graph TD;A-- text including URL space --xB;');
const vert = flow.parser.yy.getVertices();
@ -265,7 +265,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including URL space');
});
it('should handle space and dir (TD2)', function() {
it('should handle space and dir (TD2)', function () {
const res = flow.parser.parse('graph TD;A-- text including R TD space --xB;');
const vert = flow.parser.yy.getVertices();
@ -274,7 +274,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].type).toBe('arrow_cross');
expect(edges[0].text).toBe('text including R TD space');
});
it('should handle keywords', function() {
it('should handle keywords', function () {
const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB;');
const vert = flow.parser.yy.getVertices();
@ -282,7 +282,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('text including graph space and v');
});
it('should handle keywords', function() {
it('should handle keywords', function () {
const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB[blav]');
const vert = flow.parser.yy.getVertices();
@ -301,8 +301,8 @@ describe('[Text] when parsing', () => {
// });
});
describe('it should handle text in vertices, ', function() {
it('it should handle space', function() {
describe('it should handle text in vertices, ', function () {
it('it should handle space', function () {
const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar);');
const vert = flow.parser.yy.getVertices();
@ -311,7 +311,7 @@ describe('[Text] when parsing', () => {
expect(vert['C'].type).toBe('round');
expect(vert['C'].text).toBe('Chimpansen hoppar');
});
it('it should handle åäö and minus', function() {
it('it should handle åäö and minus', function () {
const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};');
const vert = flow.parser.yy.getVertices();
@ -321,7 +321,7 @@ describe('[Text] when parsing', () => {
expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ');
});
it('it should handle with åäö, minus and space and br', function() {
it('it should handle with åäö, minus and space and br', function () {
const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar åäö <br> - ÅÄÖ);');
const vert = flow.parser.yy.getVertices();
@ -339,21 +339,21 @@ describe('[Text] when parsing', () => {
// expect(vert['C'].type).toBe('round');
// expect(vert['C'].text).toBe(' A[Object&#40;foo,bar&#41;]-->B(Thing);');
// });
it('it should handle unicode chars', function() {
it('it should handle unicode chars', function () {
const res = flow.parser.parse('graph TD;A-->C(Начало);');
const vert = flow.parser.yy.getVertices();
expect(vert['C'].text).toBe('Начало');
});
it('it should handle backslask', function() {
it('it should handle backslask', function () {
const res = flow.parser.parse('graph TD;A-->C(c:\\windows);');
const vert = flow.parser.yy.getVertices();
expect(vert['C'].text).toBe('c:\\windows');
});
it('it should handle CAPS', function() {
it('it should handle CAPS', function () {
const res = flow.parser.parse('graph TD;A-->C(some CAPS);');
const vert = flow.parser.yy.getVertices();
@ -362,7 +362,7 @@ describe('[Text] when parsing', () => {
expect(vert['C'].type).toBe('round');
expect(vert['C'].text).toBe('some CAPS');
});
it('it should handle directions', function() {
it('it should handle directions', function () {
const res = flow.parser.parse('graph TD;A-->C(some URL);');
const vert = flow.parser.yy.getVertices();
@ -373,7 +373,7 @@ describe('[Text] when parsing', () => {
});
});
it('should handle multi-line text', function() {
it('should handle multi-line text', function () {
const res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;');
const vert = flow.parser.yy.getVertices();
@ -393,7 +393,7 @@ describe('[Text] when parsing', () => {
expect(edges[1].text).toBe('more text with space');
});
it('should handle text in vertices with space', function() {
it('should handle text in vertices with space', function () {
const res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;');
const vert = flow.parser.yy.getVertices();
@ -403,7 +403,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('chimpansen hoppar');
});
it('should handle text in vertices with space with spaces between vertices and link', function() {
it('should handle text in vertices with space with spaces between vertices and link', function () {
const res = flow.parser.parse('graph TD;A[chimpansen hoppar] --> C;');
const vert = flow.parser.yy.getVertices();
@ -412,7 +412,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].type).toBe('square');
expect(vert['A'].text).toBe('chimpansen hoppar');
});
it('should handle text including _ in vertices', function() {
it('should handle text including _ in vertices', function () {
const res = flow.parser.parse('graph TD;A[chimpansen_hoppar] --> C;');
const vert = flow.parser.yy.getVertices();
@ -422,7 +422,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('chimpansen_hoppar');
});
it('should handle quoted text in vertices ', function() {
it('should handle quoted text in vertices ', function () {
const res = flow.parser.parse('graph TD;A["chimpansen hoppar ()[]"] --> C;');
const vert = flow.parser.yy.getVertices();
@ -432,7 +432,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('chimpansen hoppar ()[]');
});
it('should handle text in circle vertices with space', function() {
it('should handle text in circle vertices with space', function () {
const res = flow.parser.parse('graph TD;A((chimpansen hoppar))-->C;');
const vert = flow.parser.yy.getVertices();
@ -442,7 +442,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('chimpansen hoppar');
});
it('should handle text in ellipse vertices', function() {
it('should handle text in ellipse vertices', function () {
const res = flow.parser.parse('graph TD\nA(-this is an ellipse-)-->B');
const vert = flow.parser.yy.getVertices();
@ -452,7 +452,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('this is an ellipse');
});
it('should handle text in diamond vertices with space', function() {
it('should handle text in diamond vertices with space', function () {
const res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;');
const vert = flow.parser.yy.getVertices();
@ -462,7 +462,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('chimpansen hoppar');
});
it('should handle text in with ?', function() {
it('should handle text in with ?', function () {
const res = flow.parser.parse('graph TD;A(?)-->|?|C;');
const vert = flow.parser.yy.getVertices();
@ -471,7 +471,7 @@ describe('[Text] when parsing', () => {
expect(vert['A'].text).toBe('?');
expect(edges[0].text).toBe('?');
});
it('should handle text in with éèêàçô', function() {
it('should handle text in with éèêàçô', function () {
const res = flow.parser.parse('graph TD;A(éèêàçô)-->|éèêàçô|C;');
const vert = flow.parser.yy.getVertices();
@ -481,7 +481,7 @@ describe('[Text] when parsing', () => {
expect(edges[0].text).toBe('éèêàçô');
});
it('should handle text in with ,.?!+-*', function() {
it('should handle text in with ,.?!+-*', function () {
const res = flow.parser.parse('graph TD;A(,.?!+-*)-->|,.?!+-*|C;');
const vert = flow.parser.yy.getVertices();

View File

@ -3,17 +3,17 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing flowcharts', function() {
beforeEach(function() {
describe('when parsing flowcharts', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
it('should handle chaining of vertices', function() {
it('should handle chaining of vertices', function () {
const res = flow.parser.parse(`
graph TD
A-->B-->C;
@ -35,7 +35,7 @@ describe('when parsing flowcharts', function() {
expect(edges[1].type).toBe('arrow_point');
expect(edges[1].text).toBe('');
});
it('should handle chaining of vertices', function() {
it('should handle chaining of vertices', function () {
const res = flow.parser.parse(`
graph TD
A & B --> C;
@ -57,7 +57,7 @@ describe('when parsing flowcharts', function() {
expect(edges[1].type).toBe('arrow_point');
expect(edges[1].text).toBe('');
});
it('should multiple vertices in link statement in the begining', function() {
it('should multiple vertices in link statement in the begining', function () {
const res = flow.parser.parse(`
graph TD
A-->B & C;
@ -79,7 +79,7 @@ describe('when parsing flowcharts', function() {
expect(edges[1].type).toBe('arrow_point');
expect(edges[1].text).toBe('');
});
it('should multiple vertices in link statement at the end', function() {
it('should multiple vertices in link statement at the end', function () {
const res = flow.parser.parse(`
graph TD
A & B--> C & D;
@ -110,7 +110,7 @@ describe('when parsing flowcharts', function() {
expect(edges[3].type).toBe('arrow_point');
expect(edges[3].text).toBe('');
});
it('should handle chaining of vertices at both ends at once', function() {
it('should handle chaining of vertices at both ends at once', function () {
const res = flow.parser.parse(`
graph TD
A & B--> C & D;
@ -141,7 +141,7 @@ describe('when parsing flowcharts', function() {
expect(edges[3].type).toBe('arrow_point');
expect(edges[3].text).toBe('');
});
it('should handle chaining and multiple nodes in in link statement FVC ', function() {
it('should handle chaining and multiple nodes in in link statement FVC ', function () {
const res = flow.parser.parse(`
graph TD
A --> B & B2 & C --> D2;
@ -181,7 +181,7 @@ describe('when parsing flowcharts', function() {
expect(edges[5].type).toBe('arrow_point');
expect(edges[5].text).toBe('');
});
it('should handle chaining and multiple nodes in in link statement with extra info in statements', function() {
it('should handle chaining and multiple nodes in in link statement with extra info in statements', function () {
const res = flow.parser.parse(`
graph TD
A[ h ] -- hello --> B[" test "]:::exClass & C --> D;

View File

@ -3,16 +3,16 @@ import flow from './flow';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing ', function() {
beforeEach(function() {
describe('when parsing ', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
});
it('it should handle a trailing whitespaces after statememnts', function() {
it('it should handle a trailing whitespaces after statememnts', function () {
const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;');
const vert = flow.parser.yy.getVertices();
@ -27,7 +27,7 @@ describe('when parsing ', function() {
expect(edges[0].text).toBe('');
});
it('should handle node names with "end" substring', function() {
it('should handle node names with "end" substring', function () {
const res = flow.parser.parse('graph TD\nendpoint --> sender');
const vert = flow.parser.yy.getVertices();
@ -39,7 +39,7 @@ describe('when parsing ', function() {
expect(edges[0].end).toBe('sender');
});
it('should handle node names ending with keywords', function() {
it('should handle node names ending with keywords', function () {
const res = flow.parser.parse('graph TD\nblend --> monograph');
const vert = flow.parser.yy.getVertices();
@ -51,8 +51,8 @@ describe('when parsing ', function() {
expect(edges[0].end).toBe('monograph');
});
describe('special characters should be be handled.', function() {
const charTest = function(char, result) {
describe('special characters should be be handled.', function () {
const charTest = function (char, result) {
const res = flow.parser.parse('graph TD;A(' + char + ')-->B;');
const vert = flow.parser.yy.getVertices();
@ -68,7 +68,7 @@ describe('when parsing ', function() {
flow.parser.yy.clear();
};
it("it should be able to parse a '.'", function() {
it("it should be able to parse a '.'", function () {
charTest('.');
charTest('Start 103a.a1');
});
@ -77,27 +77,27 @@ describe('when parsing ', function() {
// charTest('_')
// })
it("it should be able to parse a ':'", function() {
it("it should be able to parse a ':'", function () {
charTest(':');
});
it("it should be able to parse a ','", function() {
it("it should be able to parse a ','", function () {
charTest(',');
});
it("it should be able to parse text containing '-'", function() {
it("it should be able to parse text containing '-'", function () {
charTest('a-b');
});
it("it should be able to parse a '+'", function() {
it("it should be able to parse a '+'", function () {
charTest('+');
});
it("it should be able to parse a '*'", function() {
it("it should be able to parse a '*'", function () {
charTest('*');
});
it("it should be able to parse a '<'", function() {
it("it should be able to parse a '<'", function () {
charTest('<', '&lt;');
});
@ -105,16 +105,15 @@ describe('when parsing ', function() {
// charTest('>', '&gt;');
// });
// it("it should be able to parse a '='", function() {
// charTest('=', '&equals;');
// });
it("it should be able to parse a '&'", function() {
it("it should be able to parse a '&'", function () {
charTest('&');
});
});
it('should be possible to use direction in node ids', function() {
it('should be possible to use direction in node ids', function () {
let statement = '';
statement = statement + 'graph TD;' + '\n';
@ -126,7 +125,7 @@ describe('when parsing ', function() {
expect(vertices['node1TB'].id).toBe('node1TB');
});
it('should be possible to use direction in node ids', function() {
it('should be possible to use direction in node ids', function () {
let statement = '';
statement = statement + 'graph TD;A--x|text including URL space|B;';
@ -135,7 +134,7 @@ describe('when parsing ', function() {
const classes = flow.parser.yy.getClasses();
expect(vertices['A'].id).toBe('A');
});
it('should be possible to use numbers as labels', function() {
it('should be possible to use numbers as labels', function () {
let statement = '';
statement = statement + 'graph TB;subgraph "number as labels";1;end;';

View File

@ -4,16 +4,16 @@ import filter from 'lodash/filter';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing subgraphs', function() {
beforeEach(function() {
describe('when parsing subgraphs', function () {
beforeEach(function () {
flow.parser.yy = flowDb;
flow.parser.yy.clear();
flow.parser.yy.setGen('gen-2');
});
it('should handle subgraph with tab indentation', function() {
it('should handle subgraph with tab indentation', function () {
const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
@ -25,7 +25,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.title).toBe('One');
expect(subgraph.id).toBe('One');
});
it('should handle subgraph with chaining nodes indentation', function() {
it('should handle subgraph with chaining nodes indentation', function () {
const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2-->a3\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
@ -38,7 +38,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.id).toBe('One');
});
it('should handle subgraph with multiple words in title', function() {
it('should handle subgraph with multiple words in title', function () {
const res = flow.parser.parse('graph TB\nsubgraph "Some Title"\n\ta1-->a2\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
@ -50,7 +50,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.id).toBe('subGraph0');
});
it('should handle subgraph with id and title notation', function() {
it('should handle subgraph with id and title notation', function () {
const res = flow.parser.parse('graph TB\nsubgraph some-id[Some Title]\n\ta1-->a2\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
@ -62,7 +62,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.id).toBe('some-id');
});
xit('should handle subgraph without id and space in title', function() {
xit('should handle subgraph without id and space in title', function () {
const res = flow.parser.parse('graph TB\nsubgraph Some Title\n\ta1-->a2\nend');
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(1);
@ -74,7 +74,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.id).toBe('some-id');
});
it('should handle subgraph id starting with a number', function() {
it('should handle subgraph id starting with a number', function () {
const res = flow.parser.parse(`graph TD
A[Christmas] -->|Get money| B(Go shopping)
subgraph 1test
@ -89,7 +89,7 @@ describe('when parsing subgraphs', function() {
expect(subgraph.id).toBe('1test');
});
it('should handle subgraphs1', function() {
it('should handle subgraphs1', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -97,7 +97,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with title in quotes', function() {
it('should handle subgraphs with title in quotes', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph "title in quotes";c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -111,7 +111,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs in old style that was broken', function() {
it('should handle subgraphs in old style that was broken', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph old style that is broken;c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -125,7 +125,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with dashes in the title', function() {
it('should handle subgraphs with dashes in the title', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph a-b-c;c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -139,7 +139,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with id and title in brackets', function() {
it('should handle subgraphs with id and title in brackets', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph uid1[text of doom];c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -154,7 +154,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with id and title in brackets and quotes', function() {
it('should handle subgraphs with id and title in brackets and quotes', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph uid2["text of doom"];c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -169,7 +169,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with id and title in brackets without spaces', function() {
it('should handle subgraphs with id and title in brackets without spaces', function () {
const res = flow.parser.parse('graph TD;A-->B;subgraph uid2[textofdoom];c-->d;end;');
const vert = flow.parser.yy.getVertices();
@ -185,7 +185,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs2', function() {
it('should handle subgraphs2', function () {
const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n');
const vert = flow.parser.yy.getVertices();
@ -194,7 +194,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs3', function() {
it('should handle subgraphs3', function () {
const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle \n\n c-->d \nend\n');
const vert = flow.parser.yy.getVertices();
@ -203,7 +203,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle nested subgraphs', function() {
it('should handle nested subgraphs', function () {
const str =
'graph TD\n' +
'A-->B\n' +
@ -215,7 +215,7 @@ describe('when parsing subgraphs', function() {
const res = flow.parser.parse(str);
});
it('should handle subgraphs4', function() {
it('should handle subgraphs4', function () {
const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;');
const vert = flow.parser.yy.getVertices();
@ -224,7 +224,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs5', function() {
it('should handle subgraphs5', function () {
const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;');
const vert = flow.parser.yy.getVertices();
@ -232,7 +232,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle subgraphs with multi node statements in it', function() {
it('should handle subgraphs with multi node statements in it', function () {
const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\na & b --> c & e\n end;');
const vert = flow.parser.yy.getVertices();
@ -240,7 +240,7 @@ describe('when parsing subgraphs', function() {
expect(edges[0].type).toBe('arrow_point');
});
it('should handle nested subgraphs 1', function() {
it('should handle nested subgraphs 1', function () {
const res = flow.parser.parse(`flowchart TB
subgraph A
b-->B
@ -254,8 +254,8 @@ describe('when parsing subgraphs', function() {
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(2);
const subgraphA = filter(subgraphs,o => o.id === 'A')[0];
const subgraphB = filter(subgraphs,o => o.id === 'B')[0];
const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0];
const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0];
expect(subgraphB.nodes[0]).toBe('c');
expect(subgraphA.nodes).toContain('B');
@ -263,7 +263,7 @@ describe('when parsing subgraphs', function() {
expect(subgraphA.nodes).toContain('a');
expect(subgraphA.nodes).not.toContain('c');
});
it('should handle nested subgraphs 2', function() {
it('should handle nested subgraphs 2', function () {
const res = flow.parser.parse(`flowchart TB
b-->B
a-->c
@ -279,8 +279,8 @@ describe('when parsing subgraphs', function() {
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(2);
const subgraphA = filter(subgraphs,o => o.id === 'A')[0];
const subgraphB = filter(subgraphs,o => o.id === 'B')[0];
const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0];
const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0];
expect(subgraphB.nodes[0]).toBe('c');
expect(subgraphA.nodes).toContain('B');
@ -288,7 +288,7 @@ describe('when parsing subgraphs', function() {
expect(subgraphA.nodes).toContain('a');
expect(subgraphA.nodes).not.toContain('c');
});
it('should handle nested subgraphs 3', function() {
it('should handle nested subgraphs 3', function () {
const res = flow.parser.parse(`flowchart TB
subgraph B
c
@ -302,8 +302,8 @@ describe('when parsing subgraphs', function() {
const subgraphs = flow.parser.yy.getSubGraphs();
expect(subgraphs.length).toBe(2);
const subgraphA = filter(subgraphs,o => o.id === 'A')[0];
const subgraphB = filter(subgraphs,o => o.id === 'B')[0];
const subgraphA = filter(subgraphs, (o) => o.id === 'A')[0];
const subgraphB = filter(subgraphs, (o) => o.id === 'B')[0];
expect(subgraphB.nodes[0]).toBe('c');
expect(subgraphA.nodes).toContain('B');
expect(subgraphA.nodes).toContain('b');

View File

@ -1,13 +1,12 @@
/* eslint-env jasmine */
import moment from 'moment-mini';
import ganttDb from './ganttDb';
describe('when using the ganttDb', function() {
beforeEach(function() {
describe('when using the ganttDb', function () {
beforeEach(function () {
ganttDb.clear();
});
describe('when using relative times', function() {
describe('when using relative times', function () {
it.each`
diff | date | expected
${' 1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()}
@ -17,8 +16,8 @@ describe('when using the ganttDb', function() {
});
});
describe('when calling the clear function', function() {
beforeEach(function() {
describe('when calling the clear function', function () {
beforeEach(function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.enableInclusiveEndDates();
ganttDb.setTodayMarker('off');
@ -83,7 +82,7 @@ describe('when using the ganttDb', function() {
expStartDate2,
expEndDate2,
expId2,
expTask2
expTask2,
}) => {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection(section);
@ -99,7 +98,7 @@ describe('when using the ganttDb', function() {
}
);
it('should handle relative start date based on id regardless of sections', function() {
it('should handle relative start date based on id regardless of sections', function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection('testa1');
ganttDb.addTask('test1', 'id1,2013-01-01,2w');
@ -119,7 +118,7 @@ describe('when using the ganttDb', function() {
expect(tasks[2].startTime).toEqual(new Date(2013, 0, 15));
expect(tasks[2].endTime).toEqual(new Date(2013, 0, 17));
});
it('should ignore weekends', function() {
it('should ignore weekends', function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.setExcludes('weekends 2019-02-06,friday');
ganttDb.addSection('weekends skip test');
@ -176,7 +175,7 @@ describe('when using the ganttDb', function() {
expect(tasks[6].task).toEqual('test7');
});
it('should maintain the order in which tasks are created', function() {
it('should maintain the order in which tasks are created', function () {
ganttDb.setTitle('Project Execution');
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection('section A section');
@ -275,7 +274,9 @@ describe('when using the ganttDb', function() {
expect(tasks[10].task).toEqual('Describe gantt syntax');
expect(tasks[11].startTime).toEqual(moment('2014-01-11', 'YYYY-MM-DD').toDate());
expect(tasks[11].endTime).toEqual(moment('2014-01-11 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
expect(tasks[11].endTime).toEqual(
moment('2014-01-11 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate()
);
expect(tasks[11].order).toEqual(11);
expect(tasks[11].id).toEqual('task7');
expect(tasks[11].task).toEqual('Add gantt diagram to demo page');
@ -294,20 +295,25 @@ describe('when using the ganttDb', function() {
expect(tasks[13].task).toEqual('Describe gantt syntax');
expect(tasks[14].startTime).toEqual(moment('2014-01-16', 'YYYY-MM-DD').toDate());
expect(tasks[14].endTime).toEqual(moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
expect(tasks[14].endTime).toEqual(
moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate()
);
expect(tasks[14].order).toEqual(14);
expect(tasks[14].id).toEqual('task9');
expect(tasks[14].task).toEqual('Add gantt diagram to demo page');
expect(tasks[15].startTime).toEqual(moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
expect(tasks[15].endTime).toEqual(moment('2014-01-18 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate());
expect(tasks[15].startTime).toEqual(
moment('2014-01-16 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate()
);
expect(tasks[15].endTime).toEqual(
moment('2014-01-18 20:00:00', 'YYYY-MM-DD HH:mm:ss').toDate()
);
expect(tasks[15].order).toEqual(15);
expect(tasks[15].id).toEqual('task10');
expect(tasks[15].task).toEqual('Add another diagram to demo page');
});
it('should work when end date is the 31st', function() {
it('should work when end date is the 31st', function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.addSection('Task endTime is on the 31st day of the month');
ganttDb.addTask('test1', 'id1,2019-09-30,11d');
@ -327,14 +333,14 @@ describe('when using the ganttDb', function() {
expect(tasks[1].task).toEqual('test2');
});
describe('when setting inclusive end dates', function() {
beforeEach(function() {
describe('when setting inclusive end dates', function () {
beforeEach(function () {
ganttDb.setDateFormat('YYYY-MM-DD');
ganttDb.enableInclusiveEndDates();
ganttDb.addTask('test1', 'id1,2019-02-01,1d');
ganttDb.addTask('test2', 'id2,2019-02-01,2019-02-03');
});
it('should automatically add one day to all end dates', function() {
it('should automatically add one day to all end dates', function () {
const tasks = ganttDb.getTasks();
expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate());
expect(tasks[0].endTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate());

View File

@ -1,44 +1,42 @@
/* eslint-env jasmine */
/* eslint-disable no-eval */
import { parser } from './gantt';
import ganttDb from '../ganttDb';
const spyOn = jest.spyOn;
const parserFnConstructor = str => {
const parserFnConstructor = (str) => {
return () => {
parser.parse(str);
};
};
describe('when parsing a gantt diagram it', function() {
beforeEach(function() {
describe('when parsing a gantt diagram it', function () {
beforeEach(function () {
parser.yy = ganttDb;
parser.yy.clear();
});
it('should handle a dateFormat definition', function() {
it('should handle a dateFormat definition', function () {
const str = 'gantt\ndateFormat yyyy-mm-dd';
expect(parserFnConstructor(str)).not.toThrow();
});
it('should handle a inclusive end date definition', function() {
it('should handle a inclusive end date definition', function () {
const str = 'gantt\ndateFormat yyyy-mm-dd\ninclusiveEndDates';
expect(parserFnConstructor(str)).not.toThrow();
});
it('should handle a title definition', function() {
it('should handle a title definition', function () {
const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid';
expect(parserFnConstructor(str)).not.toThrow();
});
it('should handle an excludes definition', function() {
it('should handle an excludes definition', function () {
const str =
'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid\nexcludes weekdays 2019-02-01';
expect(parserFnConstructor(str)).not.toThrow();
});
it('should handle a todayMarker definition', function() {
it('should handle a todayMarker definition', function () {
spyOn(ganttDb, 'setTodayMarker');
const str =
'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid\nexcludes weekdays 2019-02-01\ntodayMarker off';
@ -46,7 +44,7 @@ describe('when parsing a gantt diagram it', function() {
expect(parserFnConstructor(str)).not.toThrow();
expect(ganttDb.setTodayMarker).toHaveBeenCalledWith('off');
});
it('should handle a section definition', function() {
it('should handle a section definition', function () {
const str =
'gantt\n' +
'dateFormat yyyy-mm-dd\n' +
@ -56,7 +54,7 @@ describe('when parsing a gantt diagram it', function() {
expect(parserFnConstructor(str)).not.toThrow();
});
it('should handle multiline section titles with different line breaks', function() {
it('should handle multiline section titles with different line breaks', function () {
const str =
'gantt\n' +
'dateFormat yyyy-mm-dd\n' +
@ -68,16 +66,16 @@ describe('when parsing a gantt diagram it', function() {
});
/**
* Beslutsflöde inligt nedan. Obs bla bla bla
* ```
* graph TD
* A[Hard pledge] -- text on link -->B(Round edge)
* B --> C{to do or not to do}
* C -->|Too| D[Result one]
* C -->|Doo| E[Result two]
```
* params bapa - a unique bapap
*
* graph TD
* A[Hard pledge] -- text on link -->B(Round edge)
* B --> C{to do or not to do}
* C -->|Too| D[Result one]
* C -->|Doo| E[Result two]
*
* Params bapa - a unique bapap
*/
it('should handle a task definition', function() {
it('should handle a task definition', function () {
const str =
'gantt\n' +
'dateFormat YYYY-MM-DD\n' +
@ -117,7 +115,7 @@ describe('when parsing a gantt diagram it', function() {
const tasks = parser.yy.getTasks();
allowedTags.forEach(function(t) {
allowedTags.forEach(function (t) {
if (eval(t)) {
expect(tasks[0][t]).toBeTruthy();
} else {
@ -125,7 +123,7 @@ describe('when parsing a gantt diagram it', function() {
}
});
});
it('should parse callback specifier with no args', function() {
it('should parse callback specifier with no args', function () {
spyOn(ganttDb, 'setClickEvent');
const str =
'gantt\n' +
@ -139,7 +137,7 @@ describe('when parsing a gantt diagram it', function() {
expect(parserFnConstructor(str)).not.toThrow();
expect(ganttDb.setClickEvent).toHaveBeenCalledWith('cl2', 'ganttTestClick', null);
});
it('should parse callback specifier with arbitrary number of args', function() {
it('should parse callback specifier with arbitrary number of args', function () {
spyOn(ganttDb, 'setClickEvent');
const str =
'gantt\n' +
@ -152,7 +150,10 @@ describe('when parsing a gantt diagram it', function() {
expect(parserFnConstructor(str)).not.toThrow();
const args = '"test1", "test2", "test3"';
expect(ganttDb.setClickEvent).toHaveBeenCalledWith('cl2', 'ganttTestClick', '"test0", test1, test2');
expect(ganttDb.setClickEvent).toHaveBeenCalledWith(
'cl2',
'ganttTestClick',
'"test0", test1, test2'
);
});
});

View File

@ -1,4 +1,4 @@
/* eslint-env jasmine */
// Todo reintroduce without cryptoRandomString
import gitGraphAst from './gitGraphAst';
import { parser } from './parser/gitGraph';

View File

@ -1,12 +1,11 @@
/* eslint-env jasmine */
describe('when parsing an info graph it', function() {
describe('when parsing an info graph it', function () {
var ex;
beforeEach(function() {
beforeEach(function () {
ex = require('./parser/info').parser;
ex.yy = require('./infoDb');
});
it('should handle an info definition', function() {
it('should handle an info definition', function () {
var str = `info
showInfo`;

View File

@ -1,18 +1,17 @@
/* eslint-env jasmine */
import pieDb from '../pieDb';
import pie from './pie';
import { setConfig } from '../../../config';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing pie', function() {
beforeEach(function() {
describe('when parsing pie', function () {
beforeEach(function () {
pie.parser.yy = pieDb;
pie.parser.yy.clear();
});
it('should handle very simple pie', function() {
it('should handle very simple pie', function () {
const res = pie.parser.parse(`pie
"ash" : 100
`);
@ -20,7 +19,7 @@ describe('when parsing pie', function() {
const section1 = sections['ash'];
expect(section1).toBe(100);
});
it('should handle simple pie', function() {
it('should handle simple pie', function () {
const res = pie.parser.parse(`pie
"ash" : 60
"bat" : 40
@ -29,7 +28,7 @@ describe('when parsing pie', function() {
const section1 = sections['ash'];
expect(section1).toBe(60);
});
it('should handle simple pie with comments', function() {
it('should handle simple pie with comments', function () {
const res = pie.parser.parse(`pie
%% comments
"ash" : 60
@ -40,7 +39,7 @@ describe('when parsing pie', function() {
expect(section1).toBe(60);
});
it('should handle simple pie with a directive', function() {
it('should handle simple pie with a directive', function () {
const res = pie.parser.parse(`%%{init: {'logLevel':0}}%%
pie
"ash" : 60
@ -51,7 +50,7 @@ pie
expect(section1).toBe(60);
});
it('should handle simple pie with a title', function() {
it('should handle simple pie with a title', function () {
const res = pie.parser.parse(`pie title a 60/40 pie
"ash" : 60
"bat" : 40
@ -63,7 +62,7 @@ pie
expect(title).toBe('a 60/40 pie');
});
it('should handle simple pie with positive decimal', function() {
it('should handle simple pie with positive decimal', function () {
const res = pie.parser.parse(`pie
"ash" : 60.67
"bat" : 40
@ -73,7 +72,7 @@ pie
expect(section1).toBe(60.67);
});
it('should handle simple pie with negative decimal', function() {
it('should handle simple pie with negative decimal', function () {
expect(() => {
pie.parser.parse(`pie
"ash" : 60.67

View File

@ -3,20 +3,19 @@ import requirementDb from '../requirementDb';
import reqDiagram from './requirementDiagram';
setConfig({
securityLevel: 'strict'
securityLevel: 'strict',
});
describe('when parsing requirement diagram it...', function() {
beforeEach(function() {
describe('when parsing requirement diagram it...', function () {
beforeEach(function () {
reqDiagram.parser.yy = requirementDb;
reqDiagram.parser.yy.clear();
});
it('will accept full requirement definition', function() {
const expectedName = "test_req";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept full requirement definition', function () {
const expectedName = 'test_req';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -30,7 +29,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -45,10 +44,10 @@ describe('when parsing requirement diagram it...', function() {
expect(Object.keys(requirementDb.getRelationships()).length).toBe(0);
});
it('will accept full element definition', function() {
const expectedName = "test_el";
const expectedType = "test_type";
const expectedDocRef = "test_ref"
it('will accept full element definition', function () {
const expectedName = 'test_el';
const expectedType = 'test_type';
const expectedDocRef = 'test_ref';
let lines = [
`requirementDiagram`,
@ -58,7 +57,7 @@ describe('when parsing requirement diagram it...', function() {
`docref: ${expectedDocRef}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -68,23 +67,18 @@ describe('when parsing requirement diagram it...', function() {
let foundElement = requirementDb.getElements()[expectedName];
expect(foundElement).toBeDefined();
expect(foundElement.type).toBe(expectedType);
expect(foundElement.docRef).toBe(
expectedDocRef);
expect(foundElement.docRef).toBe(expectedDocRef);
expect(Object.keys(requirementDb.getRelationships()).length).toBe(0);
});
it('will accept full relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept full relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.CONTAINS;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -97,11 +91,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.dst).toBe(expectedDest);
});
it('will accept "requirement" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "requirement" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.REQUIREMENT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -115,7 +109,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -124,11 +118,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "functionalRequirement" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "functionalRequirement" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.FUNCTIONAL_REQUIREMENT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -142,7 +136,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -151,11 +145,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "interfaceRequirement" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "interfaceRequirement" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.INTERFACE_REQUIREMENT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -169,7 +163,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -178,11 +172,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "performanceRequirement" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "performanceRequirement" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.PERFORMANCE_REQUIREMENT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -196,7 +190,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -205,11 +199,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "physicalRequirement" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "physicalRequirement" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.PHYSICAL_REQUIREMENT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -223,7 +217,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -232,11 +226,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "designConstraint" type of requirement definition', function() {
const expectedName = "test_req";
it('will accept "designConstraint" type of requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.DESIGN_CONSTRAINT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -250,7 +244,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -259,11 +253,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.type).toBe(expectedType);
});
it('will accept "low" type of risk requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "low" type of risk requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.LOW_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -277,7 +271,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -286,11 +280,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.risk).toBe(expectedRisk);
});
it('will accept "medium" type of risk requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "medium" type of risk requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.MED_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -304,7 +298,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -313,11 +307,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.risk).toBe(expectedRisk);
});
it('will accept "high" type of risk requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "high" type of risk requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -331,7 +325,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -340,11 +334,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.risk).toBe(expectedRisk);
});
it('will accept "Analysis" type of verification method requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "Analysis" type of verification method requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_ANALYSIS;
@ -358,7 +352,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -367,11 +361,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.verifyMethod).toBe(expectedVerifyMethod);
});
it('will accept "Inspection" type of verification method requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "Inspection" type of verification method requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_INSPECTION;
@ -385,7 +379,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -394,11 +388,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.verifyMethod).toBe(expectedVerifyMethod);
});
it('will accept "Test" type of verification method requirement definition', function() {
const expectedName = "test_req";
const expectedType = "designConstraint";
const expectedId = "test_id";
const expectedText = "the test text."
it('will accept "Test" type of verification method requirement definition', function () {
const expectedName = 'test_req';
const expectedType = 'designConstraint';
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_TEST;
@ -412,7 +406,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -421,11 +415,11 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.verifyMethod).toBe(expectedVerifyMethod);
});
it('will accept "Demonstration" type of verification method requirement definition', function() {
const expectedName = "test_req";
it('will accept "Demonstration" type of verification method requirement definition', function () {
const expectedName = 'test_req';
const expectedType = requirementDb.RequirementType.DESIGN_CONSTRAINT;
const expectedId = "test_id";
const expectedText = "the test text."
const expectedId = 'test_id';
const expectedText = 'the test text.';
const expectedRisk = requirementDb.RiskLevel.HIGH_RISK;
const expectedVerifyMethod = requirementDb.VerifyType.VERIFY_DEMONSTRATION;
@ -439,7 +433,7 @@ describe('when parsing requirement diagram it...', function() {
`verifymethod: ${expectedVerifyMethod}`,
`}`,
];
let doc = lines.join("\n");
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -448,17 +442,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundReq.verifyMethod).toBe(expectedVerifyMethod);
});
it('will accept contains relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept contains relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.CONTAINS;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -466,17 +456,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept copies relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept copies relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.COPIES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -484,17 +470,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept derives relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept derives relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.DERIVES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -502,17 +484,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept satisfies relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept satisfies relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.SATISFIES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -520,17 +498,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept verifies relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept verifies relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.VERIFIES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -538,17 +512,13 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept refines relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept refines relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.REFINES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
@ -556,22 +526,17 @@ describe('when parsing requirement diagram it...', function() {
expect(foundRelationship.type).toBe(expectedType);
});
it('will accept traces relationship definition', function() {
const expectedSrc = "a";
const expectedDest = "b";
it('will accept traces relationship definition', function () {
const expectedSrc = 'a';
const expectedDest = 'b';
const expectedType = requirementDb.Relationships.TRACES;
let lines = [
`requirementDiagram`,
``,
`${expectedSrc} - ${expectedType} -> ${expectedDest}`,
];
let doc = lines.join("\n");
let lines = [`requirementDiagram`, ``, `${expectedSrc} - ${expectedType} -> ${expectedDest}`];
let doc = lines.join('\n');
reqDiagram.parser.parse(doc);
let foundRelationship = requirementDb.getRelationships()[0];
expect(foundRelationship.type).toBe(expectedType);
});
});
});

View File

@ -1,10 +1,14 @@
/* eslint-env jasmine */
import { parser } from './parser/sequenceDiagram';
import sequenceDb from './sequenceDb';
import * as configApi from '../../config';
import renderer from './sequenceRenderer';
import mermaidAPI from '../../mermaidAPI';
/**
* @param conf
* @param key
* @param value
*/
function addConf(conf, key, value) {
if (value !== undefined) {
conf[key] = value;
@ -12,12 +16,12 @@ function addConf(conf, key, value) {
return conf;
}
describe('when parsing a sequenceDiagram', function() {
beforeEach(function() {
describe('when parsing a sequenceDiagram', function () {
beforeEach(function () {
parser.yy = sequenceDb;
parser.yy.clear();
});
it('it should handle a sequenceDiagram definition', function() {
it('it should handle a sequenceDiagram definition', function () {
const str = `
sequenceDiagram
Alice->Bob:Hello Bob, how are you?
@ -35,7 +39,7 @@ Bob-->Alice: I am good thanks!`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should not show sequence numbers per default', function() {
it('it should not show sequence numbers per default', function () {
const str = `
sequenceDiagram
Alice->Bob:Hello Bob, how are you?
@ -45,7 +49,7 @@ Bob-->Alice: I am good thanks!`;
mermaidAPI.parse(str);
expect(parser.yy.showSequenceNumbers()).toBe(false);
});
it('it should show sequence numbers when autonumber is enabled', function() {
it('it should show sequence numbers when autonumber is enabled', function () {
const str = `
sequenceDiagram
autonumber
@ -56,7 +60,7 @@ Bob-->Alice: I am good thanks!`;
mermaidAPI.parse(str);
expect(parser.yy.showSequenceNumbers()).toBe(true);
});
it('it should handle a sequenceDiagram definition with a title', function() {
it('it should handle a sequenceDiagram definition with a title', function () {
const str = `
sequenceDiagram
title: Diagram Title
@ -77,7 +81,7 @@ Bob-->Alice: I am good thanks!`;
expect(messages[2].from).toBe('Bob');
expect(title).toBe('Diagram Title');
});
it('it should space in actor names', function() {
it('it should space in actor names', function () {
const str = `
sequenceDiagram
Alice->Bob:Hello Bob, how are - you?
@ -94,7 +98,7 @@ Bob-->Alice: I am good thanks!`;
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle dashes in actor names', function() {
it('it should handle dashes in actor names', function () {
const str = `
sequenceDiagram
Alice-in-Wonderland->Bob:Hello Bob, how are - you?
@ -102,7 +106,7 @@ Bob-->Alice-in-Wonderland:I am good thanks!`;
mermaidAPI.parse(str);
const actors = parser.yy.getActors();
expect(actors["Alice-in-Wonderland"].description).toBe('Alice-in-Wonderland');
expect(actors['Alice-in-Wonderland'].description).toBe('Alice-in-Wonderland');
actors.Bob.description = 'Bob';
const messages = parser.yy.getMessages();
@ -111,7 +115,7 @@ Bob-->Alice-in-Wonderland:I am good thanks!`;
expect(messages[0].from).toBe('Alice-in-Wonderland');
expect(messages[1].from).toBe('Bob');
});
it('it should alias participants', function() {
it('it should alias participants', function () {
const str = `
sequenceDiagram
participant A as Alice
@ -132,7 +136,7 @@ B-->A: I am good thanks!`;
expect(messages[0].from).toBe('A');
expect(messages[1].from).toBe('B');
});
it('it should alias a mix of actors and participants apa12', function() {
it('it should alias a mix of actors and participants apa12', function () {
const str = `
sequenceDiagram
actor Alice as Alice2
@ -160,7 +164,7 @@ sequenceDiagram
expect(messages[0].from).toBe('Alice');
expect(messages[4].to).toBe('Joan');
});
it('it should alias actors apa13', function() {
it('it should alias actors apa13', function () {
const str = `
sequenceDiagram
actor A as Alice
@ -180,7 +184,7 @@ B-->A: I am good thanks!`;
expect(messages[0].from).toBe('A');
expect(messages[1].from).toBe('B');
});
it('it should handle in async messages', function() {
it('it should handle in async messages', function () {
const str = `
sequenceDiagram
Alice-xBob:Hello Bob, how are you?`;
@ -195,7 +199,7 @@ Alice-xBob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS);
});
it('it should handle in async dotted messages', function() {
it('it should handle in async dotted messages', function () {
const str = `
sequenceDiagram
Alice--xBob:Hello Bob, how are you?`;
@ -210,7 +214,7 @@ Alice--xBob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS);
});
it('it should handle in sync messages', function() {
it('it should handle in sync messages', function () {
const str = `
sequenceDiagram
Alice-)Bob:Hello Bob, how are you?`;
@ -225,7 +229,7 @@ Alice-)Bob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_POINT);
});
it('it should handle in sync dotted messages', function() {
it('it should handle in sync dotted messages', function () {
const str = `
sequenceDiagram
Alice--)Bob:Hello Bob, how are you?`;
@ -240,7 +244,7 @@ Alice--)Bob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_POINT);
});
it('it should handle in arrow messages', function() {
it('it should handle in arrow messages', function () {
const str = `
sequenceDiagram
Alice->>Bob:Hello Bob, how are you?`;
@ -255,7 +259,7 @@ Alice->>Bob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID);
});
it('it should handle in arrow messages', function() {
it('it should handle in arrow messages', function () {
const str = 'sequenceDiagram\n' + 'Alice-->>Bob:Hello Bob, how are you?';
mermaidAPI.parse(str);
@ -268,7 +272,7 @@ Alice->>Bob:Hello Bob, how are you?`;
expect(messages.length).toBe(1);
expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED);
});
it('it should handle actor activation', function() {
it('it should handle actor activation', function () {
const str = `
sequenceDiagram
Alice-->>Bob:Hello Bob, how are you?
@ -291,7 +295,7 @@ deactivate Bob`;
expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
expect(messages[3].from.actor).toBe('Bob');
});
it('it should handle actor one line notation activation', function() {
it('it should handle actor one line notation activation', function () {
const str = `
sequenceDiagram
Alice-->>+Bob:Hello Bob, how are you?
@ -312,7 +316,7 @@ deactivate Bob`;
expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
expect(messages[3].from.actor).toBe('Bob');
});
it('it should handle stacked activations', function() {
it('it should handle stacked activations', function () {
const str = `
sequenceDiagram
Alice-->>+Bob:Hello Bob, how are you?
@ -339,7 +343,7 @@ deactivate Bob`;
expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END);
expect(messages[7].from.actor).toBe('Carol');
});
it('it should handle fail parsing when activating an inactive participant', function() {
it('it should handle fail parsing when activating an inactive participant', function () {
const str = `
sequenceDiagram
participant user as End User
@ -366,7 +370,7 @@ deactivate Bob`;
expect(error).toBe(true);
});
it('it should handle comments in a sequenceDiagram', function() {
it('it should handle comments in a sequenceDiagram', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -385,7 +389,7 @@ deactivate Bob`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle new lines in a sequenceDiagram', function() {
it('it should handle new lines in a sequenceDiagram', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -406,7 +410,7 @@ deactivate Bob`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle semicolons', function() {
it('it should handle semicolons', function () {
const str = `
sequenceDiagram;Alice->Bob: Hello Bob, how are you?;Note right of Bob: Bob thinks;Bob-->Alice: I am good thanks!;`;
@ -421,7 +425,7 @@ sequenceDiagram;Alice->Bob: Hello Bob, how are you?;Note right of Bob: Bob think
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle one leading space in lines in a sequenceDiagram', function() {
it('it should handle one leading space in lines in a sequenceDiagram', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -441,7 +445,7 @@ Bob-->Alice: I am good thanks!`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle several leading spaces in lines in a sequenceDiagram', function() {
it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -461,7 +465,7 @@ Bob-->Alice: I am good thanks!`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle several leading spaces in lines in a sequenceDiagram', function() {
it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
const str = `
sequenceDiagram
participant Alice
@ -486,7 +490,7 @@ Bob-->John: Jolly good!`;
expect(messages[0].from).toBe('Alice');
expect(messages[2].from).toBe('John');
});
it('it should handle different line breaks', function() {
it('it should handle different line breaks', function () {
const str = `
sequenceDiagram
participant 1 as multiline<br>text
@ -559,7 +563,7 @@ note right of 1:nowrap: multiline<br/>text
expect(messages[5].wrap).toBe(false);
expect(messages[6].wrap).toBe(false);
expect(messages[7].wrap).toBe(false);
})
});
it('it should handle notes and messages with wrap specified', function () {
const str = `
sequenceDiagram
@ -584,7 +588,7 @@ note right of 3:wrap: multiline<br/>text
expect(messages[1].wrap).toBe(true);
expect(messages[2].wrap).toBe(true);
expect(messages[3].wrap).toBe(true);
})
});
it('it should handle notes and messages with nowrap or line breaks', function () {
const str = `
sequenceDiagram
@ -601,8 +605,8 @@ note right of 2: single-line text
expect(messages[1].message).toBe('single-line text');
expect(messages[0].wrap).toBe(false);
expect(messages[1].wrap).toBe(false);
})
it('it should handle notes over a single actor', function() {
});
it('it should handle notes over a single actor', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -615,7 +619,7 @@ Note over Bob: Bob thinks
expect(messages[1].from).toBe('Bob');
expect(messages[1].to).toBe('Bob');
});
it('it should handle notes over multiple actors', function() {
it('it should handle notes over multiple actors', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -631,7 +635,7 @@ Note over Bob,Alice: resolution
expect(messages[2].from).toBe('Bob');
expect(messages[2].to).toBe('Alice');
});
it('it should handle loop statements', function() {
it('it should handle loop statements', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -654,7 +658,7 @@ end`;
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should add a rect around sequence', function() {
it('it should add a rect around sequence', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -678,7 +682,7 @@ end`;
expect(messages[4].type).toEqual(parser.yy.LINETYPE.RECT_END);
});
it('it should allow for nested rects', function() {
it('it should allow for nested rects', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -705,7 +709,7 @@ end`;
expect(messages[5].type).toEqual(parser.yy.LINETYPE.DOTTED_OPEN);
expect(messages[6].type).toEqual(parser.yy.LINETYPE.RECT_END);
});
it('it should handle opt statements', function() {
it('it should handle opt statements', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -728,7 +732,7 @@ end`;
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle alt statements', function() {
it('it should handle alt statements', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -754,7 +758,7 @@ end`;
expect(messages[0].from).toBe('Alice');
expect(messages[1].from).toBe('Bob');
});
it('it should handle alt statements with multiple elses', function() {
it('it should handle alt statements with multiple elses', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -781,7 +785,7 @@ end`;
expect(messages[7].from).toBe('Bob');
expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END);
});
it('it should handle par statements a sequenceDiagram', function() {
it('it should handle par statements a sequenceDiagram', function () {
const str = `
sequenceDiagram
par Parallel one
@ -808,7 +812,7 @@ end`;
expect(messages[1].from).toBe('Alice');
expect(messages[2].from).toBe('Bob');
});
it('it should handle special characters in signals', function() {
it('it should handle special characters in signals', function () {
const str = 'sequenceDiagram\n' + 'Alice->Bob: -:<>,;# comment';
mermaidAPI.parse(str);
@ -816,7 +820,7 @@ end`;
const messages = parser.yy.getMessages();
expect(messages[0].message).toBe('-:<>,');
});
it('it should handle special characters in notes', function() {
it('it should handle special characters in notes', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -827,7 +831,7 @@ Note right of Bob: -:<>,;# comment`;
const messages = parser.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in loop', function() {
it('it should handle special characters in loop', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -840,7 +844,7 @@ end`;
const messages = parser.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in opt', function() {
it('it should handle special characters in opt', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -853,7 +857,7 @@ end`;
const messages = parser.yy.getMessages();
expect(messages[1].message).toBe('-:<>,');
});
it('it should handle special characters in alt', function() {
it('it should handle special characters in alt', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -869,7 +873,7 @@ end`;
expect(messages[1].message).toBe('-:<>,');
expect(messages[3].message).toBe(',<>:-');
});
it('it should handle special characters in par', function() {
it('it should handle special characters in par', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -885,7 +889,7 @@ end`;
expect(messages[1].message).toBe('-:<>,');
expect(messages[3].message).toBe(',<>:-');
});
it('it should handle no-label loop', function() {
it('it should handle no-label loop', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -899,7 +903,7 @@ end`;
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
});
it('it should handle no-label opt', function() {
it('it should handle no-label opt', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -913,7 +917,7 @@ end`;
expect(messages[1].message).toBe('');
expect(messages[2].message).toBe('I am good thanks!');
});
it('it should handle no-label alt', function() {
it('it should handle no-label alt', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -930,7 +934,7 @@ end`;
expect(messages[3].message).toBe('');
expect(messages[4].message).toBe('I am good thanks!');
});
it('it should handle no-label par', function() {
it('it should handle no-label par', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -965,19 +969,19 @@ link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com
mermaidAPI.parse(str);
const actors = parser.yy.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/");
expect(actors.b.links["Dashboard"]).toBe("https://dashboard.contoso.com/");
expect(actors.a.links["On-Call"]).toBe("https://oncall.contoso.com/?svc=alice");
expect(actors.c.links["Dashboard"]).toBe(undefined);
expect(actors.a.links["Endpoint"]).toBe("https://alice.contoso.com");
expect(actors.a.links["Swagger"]).toBe("https://swagger.contoso.com");
expect(actors.a.links["Tests"]).toBe("https://tests.contoso.com/?svc=alice@contoso.com");
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/');
expect(actors.b.links['Dashboard']).toBe('https://dashboard.contoso.com/');
expect(actors.a.links['On-Call']).toBe('https://oncall.contoso.com/?svc=alice');
expect(actors.c.links['Dashboard']).toBe(undefined);
expect(actors.a.links['Endpoint']).toBe('https://alice.contoso.com');
expect(actors.a.links['Swagger']).toBe('https://swagger.contoso.com');
expect(actors.a.links['Tests']).toBe('https://tests.contoso.com/?svc=alice@contoso.com');
});
it('it should handle properties EXPERIMENTAL: USE WITH CAUTION', function () {
//Be aware that the syntax for "properties" is likely to be changed.
//Be aware that the syntax for "properties" is likely to be changed.
const str = `
sequenceDiagram
participant a as Alice
@ -990,16 +994,15 @@ properties b: {"class": "external-service-actor", "icon": "@computer"}
mermaidAPI.parse(str);
const actors = parser.yy.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");
expect(actors.b.properties["icon"]).toBe("@computer");
expect(actors.c.properties["class"]).toBe(undefined);
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');
expect(actors.b.properties['icon']).toBe('@computer');
expect(actors.c.properties['class']).toBe(undefined);
});
});
describe('when checking the bounds in a sequenceDiagram', function() {
describe('when checking the bounds in a sequenceDiagram', function () {
beforeAll(() => {
let conf = {
diagramMarginX: 50,
@ -1011,22 +1014,21 @@ describe('when checking the bounds in a sequenceDiagram', function() {
boxMargin: 10,
messageMargin: 40,
boxTextMargin: 15,
noteMargin: 25
noteMargin: 25,
};
mermaidAPI.initialize({ sequence: conf });
});
let conf;
beforeEach(function() {
beforeEach(function () {
mermaidAPI.reset();
parser.yy = sequenceDb;
parser.yy.clear();
renderer.bounds.init();
conf = parser.yy.getConfig();
});
it('it should handle a simple bound call', function() {
it('it should handle a simple bound call', function () {
renderer.bounds.insert(100, 100, 200, 200);
const { bounds } = renderer.bounds.getBounds();
@ -1035,8 +1037,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
expect(bounds.stopx).toBe(200);
expect(bounds.stopy).toBe(200);
});
it('it should handle an expanding bound', function() {
it('it should handle an expanding bound', function () {
renderer.bounds.insert(100, 100, 200, 200);
renderer.bounds.insert(25, 50, 300, 400);
@ -1046,8 +1047,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
it('it should handle inserts within the bound without changing the outer bounds', function() {
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);
@ -1058,8 +1058,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
it('it should handle a loop without expanding the area', function() {
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();
@ -1080,8 +1079,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
it('it should handle multiple loops withtout expanding the bounds', function() {
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();
@ -1112,8 +1110,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
expect(bounds.stopx).toBe(1000);
expect(bounds.stopy).toBe(1000);
});
it('it should handle a loop that expands the area', function() {
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();
@ -1136,7 +1133,7 @@ describe('when checking the bounds in a sequenceDiagram', function() {
});
});
describe('when rendering a sequenceDiagram APA', function() {
describe('when rendering a sequenceDiagram APA', function () {
beforeAll(() => {
let conf = {
diagramMarginX: 50,
@ -1150,12 +1147,12 @@ describe('when rendering a sequenceDiagram APA', function() {
boxTextMargin: 15,
noteMargin: 25,
wrap: false,
mirrorActors: false
mirrorActors: false,
};
configApi.setSiteConfig({ logLevel: 5, sequence: conf });
});
let conf;
beforeEach(function() {
beforeEach(function () {
mermaidAPI.reset();
conf = {
diagramMarginX: 50,
@ -1169,21 +1166,21 @@ describe('when rendering a sequenceDiagram APA', function() {
boxTextMargin: 15,
noteMargin: 25,
wrap: false,
mirrorActors: false
mirrorActors: false,
};
configApi.setSiteConfig({ logLevel: 5, sequence: conf });
parser.yy = sequenceDb;
parser.yy.clear();
// conf = parser.yy.getConfig();
});
['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) {
['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
it(`
it should handle one actor, when textPlacement is ${textPlacement}`, function() {
it should handle one actor, when textPlacement is ${textPlacement}`, function () {
const str = `
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');
@ -1195,7 +1192,7 @@ participant Alice`;
expect(bounds.stopy).toBe(conf.height);
});
});
it('it should handle same actor with different whitespace properly', function() {
it('it should handle same actor with different whitespace properly', function () {
const str = `
sequenceDiagram
participant Alice
@ -1208,7 +1205,7 @@ participant Alice
const actors = parser.yy.getActors();
expect(Object.keys(actors)).toEqual(['Alice']);
});
it('it should handle one actor and a centered note', function() {
it('it should handle one actor and a centered note', function () {
const str = `
sequenceDiagram
participant Alice
@ -1226,7 +1223,7 @@ Note over Alice: Alice thinks
// 10 comes from mock of text height
expect(bounds.stopy).toBe(models.lastNote().stopy);
});
it('it should handle one actor and a note to the left', function() {
it('it should handle one actor and a note to the left', function () {
const str = `
sequenceDiagram
participant Alice
@ -1242,7 +1239,7 @@ Note left of Alice: Alice thinks`;
// 10 comes from mock of text height
expect(bounds.stopy).toBe(models.lastNote().stopy);
});
it('it should handle one actor and a note to the right', function() {
it('it should handle one actor and a note to the right', function () {
const str = `
sequenceDiagram
participant Alice
@ -1258,7 +1255,7 @@ Note right of Alice: Alice thinks`;
// 10 comes from mock of text height
expect(bounds.stopy).toBe(models.lastNote().stopy);
});
it('it should handle two actors', function() {
it('it should handle two actors', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?`;
@ -1272,7 +1269,7 @@ Alice->Bob: Hello Bob, how are you?`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should handle two actors with init directive', function() {
it('it should handle two actors with init directive', function () {
const str = `
%%{init: {'logLevel': 0}}%%
sequenceDiagram
@ -1289,7 +1286,7 @@ Alice->Bob: Hello Bob, how are you?`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should handle two actors with init directive with multiline directive', function() {
it('it should handle two actors with init directive with multiline directive', function () {
const str = `
%%{init: { 'logLevel': 0}}%%
sequenceDiagram
@ -1309,10 +1306,9 @@ Alice->Bob: Hello Bob, how are you?`;
expect(bounds.starty).toBe(0);
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
expect(msgs.every(v => v.wrap)).toBe(true);
expect(msgs.every((v) => v.wrap)).toBe(true);
});
it('it should handle two actors and two centered shared notes', function() {
it('it should handle two actors and two centered shared notes', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -1329,7 +1325,7 @@ Note over Bob,Alice: Looks back
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastNote().stopy);
});
it('it should draw two actors and two messages', function() {
it('it should draw two actors and two messages', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -1344,7 +1340,7 @@ Bob->Alice: Fine!`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors notes to the right', function() {
it('it should draw two actors notes to the right', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -1363,7 +1359,7 @@ Bob->Alice: Fine!`;
expect(bounds.stopx).toBe(expStopX);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors notes to the left', function() {
it('it should draw two actors notes to the left', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -1380,7 +1376,7 @@ Bob->Alice: Fine!`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors notes to the left with text wrapped (inline)', function() {
it('it should draw two actors notes to the left with text wrapped (inline)', function () {
const str = `
sequenceDiagram
Alice->>Bob:wrap: 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!
@ -1399,7 +1395,7 @@ Bob->>Alice: Fine!`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors notes to the left with text wrapped (directive)', function() {
it('it should draw two actors notes to the left with text wrapped (directive)', function () {
const str = `
%%{init: { 'theme': 'dark' } }%%
sequenceDiagram
@ -1417,12 +1413,12 @@ Bob->>Alice: Fine!`;
expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2);
expect(bounds.starty).toBe(0);
expect(mermaid.theme).toBe('dark');
expect(msgs.every(v => v.wrap)).toBe(true);
expect(msgs.every((v) => v.wrap)).toBe(true);
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors notes to the left with text wrapped and the init directive sets the theme to dark', function() {
it('it should draw two actors notes to the left with text wrapped and the init directive sets the theme to dark', function () {
const str = `
%%{init:{'theme':'dark'}}%%
sequenceDiagram
@ -1440,12 +1436,12 @@ Bob->>Alice: Fine!`;
expect(bounds.startx).toBe(-(conf.width / 2) - conf.actorMargin / 2);
expect(bounds.starty).toBe(0);
expect(mermaid.theme).toBe('dark');
expect(msgs.every(v => v.wrap)).toBe(true);
expect(msgs.every((v) => v.wrap)).toBe(true);
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two actors, notes to the left with text wrapped and the init directive sets the theme to dark and fontFamily to Menlo, fontSize to 18, and fontWeight to 800', function() {
it('it should draw two actors, notes to the left with text wrapped and the init directive sets the theme to dark and fontFamily to Menlo, fontSize to 18, and fontWeight to 800', function () {
const str = `
%%{init: { "theme": "dark", 'config': { "fontFamily": "Menlo", "fontSize": 18, "messageFontWeight": 400, "wrap": true }}}%%
sequenceDiagram
@ -1464,12 +1460,12 @@ Bob->>Alice: Fine!`;
expect(mermaid.sequence.fontFamily).toBe('Menlo');
expect(mermaid.sequence.fontSize).toBe(18);
expect(mermaid.sequence.messageFontWeight).toBe(400);
expect(msgs.every(v => v.wrap)).toBe(true);
expect(msgs.every((v) => v.wrap)).toBe(true);
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastMessage().stopy + 10);
});
it('it should draw two loops', function() {
it('it should draw two loops', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
@ -1486,7 +1482,7 @@ end`;
expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin);
expect(bounds.stopy).toBe(models.lastLoop().stopy);
});
it('it should draw background rect', function() {
it('it should draw background rect', function () {
const str = `
sequenceDiagram
Alice->Bob: Hello Bob, are you alright?
@ -1505,8 +1501,7 @@ end`;
});
});
describe('when rendering a sequenceDiagram with actor mirror activated', function() {
describe('when rendering a sequenceDiagram with actor mirror activated', function () {
beforeAll(() => {
let conf = {
diagramMarginX: 50,
@ -1522,22 +1517,22 @@ describe('when rendering a sequenceDiagram with actor mirror activated', functio
mirrorActors: true,
// Depending on css styling this might need adjustment
// Prolongs the edge of the diagram downwards
bottomMarginAdj: 1
bottomMarginAdj: 1,
};
mermaidAPI.initialize({ sequence: conf });
});
let conf;
beforeEach(function() {
beforeEach(function () {
mermaidAPI.reset();
parser.yy = sequenceDb;
parser.yy.clear();
conf = parser.yy.getConfig();
renderer.bounds.init();
});
['tspan', 'fo', 'old', undefined].forEach(function(textPlacement) {
it('it should handle one actor, when textPlacement is' + textPlacement, function() {
['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();
const str = `
@ -1556,8 +1551,8 @@ participant Alice`;
});
});
describe('when rendering a sequenceDiagram with directives', function() {
beforeAll(function() {
describe('when rendering a sequenceDiagram with directives', function () {
beforeAll(function () {
let conf = {
diagramMarginX: 50,
diagramMarginY: 10,
@ -1567,13 +1562,13 @@ describe('when rendering a sequenceDiagram with directives', function() {
boxMargin: 10,
messageMargin: 40,
boxTextMargin: 15,
noteMargin: 25
noteMargin: 25,
};
mermaidAPI.initialize({ sequence: conf });
});
let conf;
beforeEach(function() {
beforeEach(function () {
mermaidAPI.reset();
parser.yy = sequenceDb;
parser.yy.clear();
@ -1581,7 +1576,7 @@ describe('when rendering a sequenceDiagram with directives', function() {
renderer.bounds.init();
});
it('it should handle one actor, when theme is dark and logLevel is 1 DX1', function() {
it('it should handle one actor, when theme is dark and logLevel is 1 DX1', function () {
const str = `
%%{init: { "theme": "dark", "logLevel": 1 } }%%
sequenceDiagram
@ -1600,9 +1595,11 @@ participant Alice
expect(bounds.startx).toBe(0);
expect(bounds.startx).toBe(0);
expect(bounds.starty).toBe(0);
expect(bounds.stopy).toBe(models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin);
expect(bounds.stopy).toBe(
models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin
);
});
it('it should handle one actor, when logLevel is 3', function() {
it('it should handle one actor, when logLevel is 3', function () {
const str = `
%%{initialize: { "logLevel": 3 }}%%
sequenceDiagram
@ -1618,6 +1615,8 @@ participant Alice
expect(bounds.startx).toBe(0);
expect(bounds.startx).toBe(0);
expect(bounds.starty).toBe(0);
expect(bounds.stopy).toBe(models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin);
expect(bounds.stopy).toBe(
models.lastActor().y + models.lastActor().height + mermaid.sequence.boxMargin
);
});
});

View File

@ -1,10 +1,9 @@
/* eslint-env jasmine */
const svgDraw = require('./svgDraw');
const { MockD3 } = require('d3');
describe('svgDraw', function() {
describe('drawRect', function() {
it('it should append a rectangle', function() {
describe('svgDraw', function () {
describe('drawRect', function () {
it('it should append a rectangle', function () {
const svg = MockD3('svg');
svgDraw.drawRect(svg, {
x: 10,
@ -15,7 +14,7 @@ describe('svgDraw', function() {
height: '20',
rx: '10',
ry: '10',
class: 'unitTestRectangleClass'
class: 'unitTestRectangleClass',
});
expect(svg.__children.length).toBe(1);
const rect = svg.__children[0];
@ -40,7 +39,7 @@ describe('svgDraw', function() {
width: '20',
height: '20',
rx: '10',
ry: '10'
ry: '10',
});
expect(svg.__children.length).toBe(1);
const rect = svg.__children[0];
@ -49,8 +48,8 @@ describe('svgDraw', function() {
expect(rect.attr).not.toHaveBeenCalledWith('class', expect.anything());
});
});
describe('drawText', function() {
it('it should append a single element', function() {
describe('drawText', function () {
it('it should append a single element', function () {
const svg = MockD3('svg');
svgDraw.drawText(svg, {
x: 10,
@ -74,7 +73,7 @@ describe('svgDraw', function() {
expect(text.style).toHaveBeenCalledWith('font-size', '10px');
expect(text.style).toHaveBeenCalledWith('font-weight', '500');
});
it('it should append a multiple elements', function() {
it('it should append a multiple elements', function () {
const svg = MockD3('svg');
svgDraw.drawText(svg, {
x: 10,
@ -101,8 +100,8 @@ describe('svgDraw', function() {
expect(text3.text).toHaveBeenCalledWith('fine lines');
});
});
describe('drawBackgroundRect', function() {
it('it should append a rect before the previous element within a given bound', function() {
describe('drawBackgroundRect', function () {
it('it should append a rect before the previous element within a given bound', function () {
const svg = MockD3('svg');
const boundingRect = {
startx: 50,
@ -110,7 +109,7 @@ describe('svgDraw', function() {
stopx: 150,
stopy: 260,
title: undefined,
fill: '#ccc'
fill: '#ccc',
};
svgDraw.drawBackgroundRect(svg, boundingRect);
expect(svg.__children.length).toBe(1);

View File

@ -1,14 +1,13 @@
/* eslint-env jasmine */
import { parser } from './parser/stateDiagram';
import stateDb from './stateDb';
describe('state diagram, ', function() {
describe('when parsing an info graph it', function() {
beforeEach(function() {
describe('state diagram, ', function () {
describe('when parsing an info graph it', function () {
beforeEach(function () {
parser.yy = stateDb;
});
it('super simple', function() {
it('super simple', function () {
const str = `
stateDiagram
[*] --> State1
@ -17,7 +16,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('simple', function() {
it('simple', function () {
const str = `stateDiagram\n
State1 : this is another string
[*] --> State1
@ -26,7 +25,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('simple with directive', function() {
it('simple with directive', function () {
const str = `%%{init: {'logLevel': 0 }}%%
stateDiagram\n
State1 : this is another string
@ -36,7 +35,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle relation definitions', function() {
it('should handle relation definitions', function () {
const str = `stateDiagram\n
[*] --> State1
State1 --> [*]
@ -49,7 +48,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('hide empty description', function() {
it('hide empty description', function () {
const str = `stateDiagram\n
hide empty description
[*] --> State1
@ -64,7 +63,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('handle "as" in state names', function() {
it('handle "as" in state names', function () {
const str = `stateDiagram
assemble
state assemble
@ -72,7 +71,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('handle "as" in state names 1', function() {
it('handle "as" in state names 1', function () {
const str = `stateDiagram
assemble
state assemble
@ -80,7 +79,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('handle "as" in state names 2', function() {
it('handle "as" in state names 2', function () {
const str = `stateDiagram
assembleas
state assembleas
@ -88,7 +87,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('handle "as" in state names 3', function() {
it('handle "as" in state names 3', function () {
const str = `stateDiagram
state "as" as as
`;
@ -96,7 +95,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('scale', function() {
it('scale', function () {
const str = `stateDiagram\n
scale 350 width
[*] --> State1
@ -111,7 +110,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('description after second state', function() {
it('description after second state', function () {
const str = `stateDiagram\n
scale 350 width
[*] --> State1 : This is the description with - in it
@ -120,7 +119,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('shall handle descriptions inkluding minus signs', function() {
it('shall handle descriptions inkluding minus signs', function () {
const str = `stateDiagram\n
scale 350 width
[*] --> State1 : This is the description +-!
@ -129,7 +128,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle state statements', function() {
it('should handle state statements', function () {
const str = `stateDiagram\n
state Configuring {
[*] --> NewValueSelection
@ -141,7 +140,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle recursive state definitions', function() {
it('should handle recursive state definitions', function () {
const str = `stateDiagram\n
state Configuring {
[*] --> NewValueSelection
@ -157,7 +156,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle multiple recursive state definitions', function() {
it('should handle multiple recursive state definitions', function () {
const str = `stateDiagram\n
scale 350 width
[*] --> NotShooting
@ -182,14 +181,14 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle state deifintions with separation of id', function() {
it('should handle state deifintions with separation of id', function () {
const str = `stateDiagram\n
state "Long state description" as state1
`;
parser.parse(str);
});
it('should handle state deifintions with separation of id', function() {
it('should handle state deifintions with separation of id', function () {
const str = `stateDiagram
state "Not Shooting State" as NotShooting {
state "Idle mode" as Idle
@ -203,7 +202,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should State definition with quotes', function() {
it('should State definition with quotes', function () {
const str = `stateDiagram\n
scale 600 width
@ -226,7 +225,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle fork statements', function() {
it('should handle fork statements', function () {
const str = `stateDiagram\n
state fork_state <<fork>>
[*] --> fork_state
@ -242,7 +241,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle concurrent state', function() {
it('should handle concurrent state', function () {
const str = `stateDiagram\n
[*] --> Active
@ -263,7 +262,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle concurrent state', function() {
it('should handle concurrent state', function () {
const str = `stateDiagram\n
[*] --> Active
@ -288,7 +287,7 @@ describe('state diagram, ', function() {
// parser.parse(str);
// });
it('should handle note statements', function() {
it('should handle note statements', function () {
const str = `stateDiagram\n
[*] --> Active
Active --> Inactive
@ -304,7 +303,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle multiline notes with different line breaks', function() {
it('should handle multiline notes with different line breaks', function () {
const str = `stateDiagram
State1
note right of State1
@ -314,7 +313,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle floating notes', function() {
it('should handle floating notes', function () {
const str = `stateDiagram
foo: bar
note "This is a floating note" as N1
@ -322,7 +321,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle floating notes', function() {
it('should handle floating notes', function () {
const str = `stateDiagram\n
state foo
note "This is a floating note" as N1
@ -330,7 +329,7 @@ describe('state diagram, ', function() {
parser.parse(str);
});
it('should handle notes for composit states', function() {
it('should handle notes for composit states', function () {
const str = `stateDiagram\n
[*] --> NotShooting
@ -348,9 +347,8 @@ describe('state diagram, ', function() {
parser.parse(str);
});
});
describe('when parsing an ignored info graph it', function() {
xit('should handle if statements', function() {
describe('when parsing an ignored info graph it', function () {
xit('should handle if statements', function () {
const str = `stateDiagram\n
[*] --> "Order Submitted"
if "Payment Accepted" then

View File

@ -70,7 +70,11 @@ const setupNode = (g, parent, node, altFlag) => {
nodeDb[node.id].shape = 'rectWithTitle';
if (nodeDb[node.id].description === node.id) {
// If the previous description was the is, remove it
nodeDb[node.id].description = [node.description];
if (Array.isArray(node.description)) {
nodeDb[node.id].description = node.description;
} else {
nodeDb[node.id].description = [node.description];
}
} else {
nodeDb[node.id].description = [nodeDb[node.id].description, node.description];
}
@ -79,10 +83,6 @@ const setupNode = (g, parent, node, altFlag) => {
nodeDb[node.id].description = node.description;
}
}
nodeDb[node.id].description = common.sanitizeTextOrArray(
nodeDb[node.id].description,
getConfig()
);
}
// Save data for description and group so that for instance a statement without description overwrites
@ -100,10 +100,17 @@ const setupNode = (g, parent, node, altFlag) => {
(altFlag ? 'statediagram-cluster statediagram-cluster-alt' : 'statediagram-cluster');
}
let nodeShape = nodeDb[node.id].shape;
let nodeLabelText = nodeDb[node.id].description;
if (Array.isArray(nodeLabelText) && nodeLabelText.length == 1) {
nodeShape = 'rect';
nodeLabelText = nodeLabelText[0];
}
const nodeData = {
labelStyle: '',
shape: nodeDb[node.id].shape,
labelText: nodeDb[node.id].description,
shape: nodeShape,
labelText: nodeLabelText,
// typeof nodeDb[node.id].description === 'object'
// ? nodeDb[node.id].description[0]
// : nodeDb[node.id].description,

Some files were not shown because too many files have changed in this diff Show More