Merge pull request #439 from whyzdev/flowchat_text

adde tests to reproduce #434 in flowchart
This commit is contained in:
Knut Sveidqvist 2016-12-19 13:04:36 +01:00 committed by GitHub
commit dfd9622ce7
14 changed files with 155 additions and 33 deletions

5
.gitignore vendored
View File

@ -7,4 +7,7 @@ bower_components
.DS_Store
.idea
coverage
coverage
test/tmp_*
test/fixtures/samples/*.actual.*

View File

@ -21,6 +21,7 @@ function cli(options) {
help: 'h'
, png: 'p'
, outputDir: 'o'
, outputSuffix: 'O'
, svg: 's'
, verbose: 'v'
, phantomPath: 'e'
@ -30,7 +31,7 @@ function cli(options) {
, width: 'w'
}
, 'boolean': ['help', 'png', 'svg', 'verbose']
, 'string': ['outputDir']
, 'string': ['outputDir', 'outputSuffix']
}
this.errors = []
@ -45,6 +46,7 @@ function cli(options) {
, " -s --svg Output SVG instead of PNG (experimental)"
, " -p --png If SVG was selected, and you also want PNG, set this flag"
, " -o --outputDir Directory to save files, will be created automatically, defaults to `cwd`"
, " -O --outputSuffix Suffix to output filenames in front of '.svg' or '.png', defaults to ''"
, " -e --phantomPath Specify the path to the phantomjs executable"
, " -t --css Specify the path to a CSS file to be included when processing output"
, " -c --sequenceConfig Specify the path to the file with the configuration to be applied in the sequence diagram"
@ -79,7 +81,7 @@ cli.prototype.parse = function(argv, next) {
}
// ensure that parameter-expecting options have parameters
;['outputDir', 'phantomPath', 'sequenceConfig', 'ganttConfig', 'css'].forEach(function(i) {
;['outputDir', 'outputSuffix', 'phantomPath', 'sequenceConfig', 'ganttConfig', 'css'].forEach(function(i) {
if(typeof options[i] !== 'undefined') {
if (typeof options[i] !== 'string' || options[i].length < 1) {
this.errors.push(new Error(i + " expects a value."))

View File

@ -12,6 +12,7 @@ module.exports = { process: processMermaid }
function processMermaid(files, _options, _next) {
var options = _options || {}
, outputDir = options.outputDir || process.cwd()
, outputSuffix = options.outputSuffix || ''
, next = _next || function() {}
, phantomArgs = [
phantomscript
@ -23,6 +24,7 @@ function processMermaid(files, _options, _next) {
, options.ganttConfig
, options.verbose
, options.width
, outputSuffix
];
files.forEach(function(file) {

View File

@ -29,7 +29,7 @@ var system = require('system')
, webpage = require('webpage')
var page = webpage.create()
, files = system.args.slice(9, system.args.length)
, files = system.args.slice(10, system.args.length)
, width = system.args[8]
if(typeof width === 'undefined' || width==='undefined'){
@ -44,6 +44,7 @@ var options = {
, ganttConfig: system.args[6] !== 'null' ? JSON.parse(fs.read(system.args[6])) : {}
, verbose: system.args[7] === 'true' ? true : false
, width: width
, outputSuffix: system.args[9]
}
, log = logger(options.verbose)
options.sequenceConfig.useMaxWidth = false;
@ -98,21 +99,21 @@ files.forEach(function(file) {
for (var i = 0, len = allElements.length; i < len; i++) {
resolveForeignObjects(allElements[i])
}
var outputPath=options.outputDir + fs.separator + filename + options.outputSuffix;
if (options.png) {
page.viewportSize = {
width: ~~oDOM.documentElement.attributes.getNamedItem('width').value
, height: ~~oDOM.documentElement.attributes.getNamedItem('height').value
}
page.render(options.outputDir + fs.separator + filename + '.png')
page.render(outputPath+'.png')
console.log('saved png: ' + filename + '.png')
}
if (options.svg) {
var serialize = new XMLSerializer();
fs.write(
options.outputDir + fs.separator + filename + '.svg'
fs.write(outputPath+'.svg'
, serialize.serializeToString(oDOM)+'\n'
, 'w'
)

View File

@ -271,16 +271,14 @@ var _drawTextCandidateFunc = (function() {
.attr('x', x + width / 2).attr('y', y + height / 2 + 5)
.style('text-anchor', 'middle')
.text(content);
for (var key in textAttrs) {
text.attr(key, textAttrs[key]);
}
};
_setTextAttrs(text, textAttrs);
}
function byTspan(content, g, x, y, width, height, textAttrs) {
var text = g.append('text')
.attr('x', x + width / 2).attr('y', y)
.style('text-anchor', 'middle');
var tspan = text.append('tspan')
text.append('tspan')
.attr('x', x + width / 2).attr('dy', '0')
.text(content);
@ -293,16 +291,13 @@ var _drawTextCandidateFunc = (function() {
if (tspans.length > 0 && tspans[0].length > 0) {
tspans = tspans[0];
//set y of <text> to the mid y of the first line
text.attr('y', y + (height/2.- text[0][0].getBBox().height*(1 - 1.0/tspans.length)/2.))
text.attr('y', y + (height/2.0 - text[0][0].getBBox().height*(1 - 1.0/tspans.length)/2.0))
.attr("dominant-baseline", "central")
.attr("alignment-baseline", "central")
.attr("alignment-baseline", "central");
}
}
for (var key in textAttrs) {
text.attr(key, textAttrs[key]);
}
};
_setTextAttrs(text, textAttrs);
}
function byFo(content, g, x, y, width, height, textAttrs) {
var s = g.append('switch');
@ -315,14 +310,19 @@ var _drawTextCandidateFunc = (function() {
text.append('div').style('display', 'table-cell')
.style('text-align', 'center').style('vertical-align', 'middle')
.text(content)
.text(content);
byTspan(content, s, x, y, width, height, textAttrs);
_setTextAttrs(text, textAttrs);
}
for (var key in textAttrs) {
text.attr(key, textAttrs[key]);
function _setTextAttrs(toText, fromTextAttrsDict) {
for (var key in fromTextAttrsDict) {
if (fromTextAttrsDict.hasOwnProperty(key)) {
toText.attr(key, fromTextAttrsDict[key]);
}
};
}
}
return function(conf) {
return conf.textPlacement==='fo' ? byFo : (

View File

@ -47,7 +47,7 @@ test('output of single png', function(t) {
var expected = ['test.mermaid.png']
opt = clone(singleFile)
var opt = clone(singleFile)
opt.outputDir += '_png'
opt.png = true
@ -64,7 +64,7 @@ test('output of multiple png', function(t) {
var expected = ['test.mermaid.png', 'test2.mermaid.png',
'gantt.mermaid.png', 'sequence.mermaid.png']
opt = clone(multiFile)
var opt = clone(multiFile)
opt.outputDir += '_png'
opt.png = true
@ -80,7 +80,7 @@ test('output of single svg', function(t) {
var expected = ['test.mermaid.svg']
opt = clone(singleFile)
var opt = clone(singleFile)
opt.outputDir += '_svg'
opt.svg = true
@ -97,7 +97,7 @@ test('output of multiple svg', function(t) {
var expected = ['test.mermaid.svg', 'test2.mermaid.svg',
'gantt.mermaid.svg', 'sequence.mermaid.svg']
opt = clone(multiFile)
var opt = clone(multiFile)
opt.outputDir += '_svg'
opt.svg = true

93
test/cli_test-samples.js Normal file
View File

@ -0,0 +1,93 @@
'use strict';
var exec = require('child_process').exec;
var path = require('path')
var test = require('tape')
, rimraf = require('rimraf')
var test_dir = 'test/fixtures/samples/'.replace('/',path.sep)
rimraf.sync(test_dir+'*.actual.*');
function exec_mermaid(args, verify) {
exec('bin/mermaid.js ' + args,
{env: {PATH: './node_modules/.bin'+path.delimiter+process.env.PATH}},
function(error, stdout, stderr) {
console.log('error:',error,'\nstdout:\n',stdout,'\nstderr:\n',stderr);
verify(error, stdout, stderr);
});
}
test('mermaid cli help', function(t) {
t.plan(1);
var args = [ '--help' ]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.notOk(stderr, 'no error')
t.end()
});
});
test('mermaid cli help', function(t) {
t.plan(1);
var args = [ '--badopt' ]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.ok(stderr, 'should get error')
t.end()
});
});
//todo
test.skip('sequence syntax error', function(t) {
t.plan(1);
var args = [ '--svg',
'--outputDir=' + test_dir,
'--outputSuffix=.actual',
test_dir+'sequence_err.mmd'
]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.ok(stderr, 'should get error')
t.end()
});
});
['', 'fo', 'tspan', 'old'].forEach(function(textPlacement) {
test('sequence svg text placelment: '+textPlacement, function(t) {
t.plan(1);
var args = [ '--svg',
'--outputDir=' + test_dir,
'--outputSuffix='+(textPlacement ? '_'+textPlacement : '')+'.actual',
textPlacement ? '--sequenceConfig='+test_dir+'sequence_text_'+textPlacement+'.cfg' : '',
test_dir+'sequence_text.mmd'
]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.notOk(stderr, 'no error')
t.end()
});
})
});
test('sequence png', function(t) {
t.plan(1);
var args = [ '--png',
'--outputDir=' + test_dir,
'--outputSuffix=.actual',
test_dir+'sequence_text.mmd'
]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.notOk(stderr, 'no error')
t.end()
});
})
test('flowchart svg text', function(t) {
t.plan(1);
var args = [ '--svg',
'--outputDir=' + test_dir,
'--outputSuffix=.actual',
test_dir+'flowchart_text.mmd'
]
exec_mermaid(args.join(' '), function(error, stdout, stderr) {
t.notOk(stderr, 'no error')
t.end()
});
})

View File

@ -0,0 +1,4 @@
graph TD
A[label]
B[very very very long long long long-long-long text]
A--test-->B

View File

@ -0,0 +1,2 @@
sequenceDiagram
bad

View File

@ -0,0 +1,6 @@
sequenceDiagram
participant A as actor
participant B as very very very long long long long-long-long text
A->>B: hi
B-->A:
B->>A: hello

View File

@ -0,0 +1,3 @@
{
"textPlacement": "fo"
}

View File

@ -0,0 +1,3 @@
{
"textPlacement": "old"
}

View File

@ -0,0 +1,3 @@
{
"textPlacement": "tspan"
}

View File

@ -1,8 +1,8 @@
sequenceDiagram
Alice->Bob: Hello Bob, how are you?
Alice->>Bob: Hello Bob, how are you?
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!
Bob-->John the Long: How about you John?
Bob-->Alice: Checking with John...
Alice->John the Long: Yes... John, how are you?
Bob-->>Alice: I am good thanks!
Bob-->>John the Long: How about you John?
Bob-->>Alice: Checking with John...
Alice->>John the Long: Yes... John, how are you?
John the Long-->Alice: Better than you!