mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Now jison can parse xAxis and yAxis
This commit is contained in:
parent
0a731e1ee1
commit
29ab2dec59
@ -12,6 +12,15 @@
|
||||
%x acc_title
|
||||
%x acc_descr
|
||||
%x acc_descr_multiline
|
||||
%x chart_config
|
||||
%x chart_orientation
|
||||
%x x_axis
|
||||
%x y_axis
|
||||
%x axis_title
|
||||
%x axis_data
|
||||
%x axis_data_band
|
||||
%x axis_data_band_capture
|
||||
%x axis_data_band_str
|
||||
%%
|
||||
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
|
||||
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
|
||||
@ -34,6 +43,34 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||
<acc_descr_multiline>[\}] { this.popState(); }
|
||||
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
|
||||
|
||||
" "*"xychart-beta" {this.begin("chart_config"); return 'XYCHART';}
|
||||
<chart_config>" "+("vertical"|"horizontal") {this.begin("chart_orientation"); return 'chart_orientation';}
|
||||
<chart_orientation>[\s]* {this.popState(); this.popState(); return 'CHART_CONFIG_END';}
|
||||
<chart_config>[\s]* {this.popState(); return 'CHART_CONFIG_END';}
|
||||
|
||||
"x-axis"" "* { this.begin("x_axis"); return "X_AXIS";}
|
||||
"y-axis"" "* { this.begin("y_axis"); return "Y_AXIS";}
|
||||
<x_axis,y_axis>["] {this.begin("axis_title");}
|
||||
<axis_title>[^"]+ {return 'AXIS_TITLE';}
|
||||
<axis_title>["]" "*(\r?\n) {this.popState(); this.popState();}
|
||||
<axis_title>["]" "* {this.popState(); this.begin("axis_data");}
|
||||
<x_axis,y_axis>[^\s]+" "*(\r?\n) {this.popState(); return 'AXIS_TITLE';}
|
||||
<x_axis,y_axis>[^\s]+" "* {this.begin("axis_data"); return 'AXIS_TITLE'; }
|
||||
|
||||
<axis_data>[+-]?\d+(\.\d+)?" "*"-->"" "*[+-]?\d+(\.\d+)?" "* { return 'AXIS_RANGE_DATA';}
|
||||
|
||||
<axis_data>[\[]" "* {this.begin("axis_data_band"); this.begin("axis_data_band_capture")}
|
||||
<axis_data_band>[,]" "* {this.begin("axis_data_band_capture")}
|
||||
<axis_data_band_capture>["] {this.begin("axis_data_band_str");}
|
||||
<axis_data_band_str>[^"]+ {return "AXIS_BAND_DATA";}
|
||||
<axis_data_band_str>["]" "* {this.popState(); this.popState();}
|
||||
<axis_data_band_capture>[^\s]+" "* {this.popState(); return "AXIS_BAND_DATA"}
|
||||
<axis_data_band>[\]]" "* {this.popState(); return "AXIS_BAND_DATA_END"}
|
||||
|
||||
|
||||
<axis_data>[\r\n]+ {this.popState(); this.popState();}
|
||||
|
||||
|
||||
|
||||
["][`] { this.begin("md_string");}
|
||||
<md_string>[^`"]+ { return "MD_STR";}
|
||||
@ -42,8 +79,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||
<string>["] this.popState();
|
||||
<string>[^"]* return "STR";
|
||||
|
||||
" "*"xychart"" "* return 'XYCHART';
|
||||
|
||||
[A-Za-z]+ return 'ALPHA';
|
||||
":" return 'COLON';
|
||||
\+ return 'PLUS';
|
||||
@ -72,9 +107,14 @@ start
|
||||
: eol start
|
||||
| SPACE start
|
||||
| directive start
|
||||
| XYCHART document
|
||||
| XYCHART chartConfig CHART_CONFIG_END document
|
||||
| XYCHART CHART_CONFIG_END document
|
||||
;
|
||||
|
||||
chartConfig
|
||||
: chart_orientation {yy.setOrientation($1.trim());}
|
||||
;
|
||||
|
||||
document
|
||||
: /* empty */
|
||||
| document line
|
||||
@ -88,8 +128,25 @@ statement
|
||||
:
|
||||
| SPACE statement
|
||||
| directive
|
||||
| X_AXIS parseXAxis
|
||||
| Y_AXIS parseYAxis
|
||||
;
|
||||
|
||||
parseXAxis
|
||||
: AXIS_TITLE {yy.setXAxisTitle($1.trim());}
|
||||
| AXIS_TITLE xAxisBandData {yy.setXAxisTitle($1.trim());}
|
||||
| AXIS_TITLE AXIS_RANGE_DATA {yy.setXAxisTitle($1.trim()); $$ = $2.split("-->"); yy.setXAxisRangeData(Number($$[0]), Number($$[1]));}
|
||||
;
|
||||
|
||||
xAxisBandData
|
||||
: AXIS_BAND_DATA xAxisBandData {yy.addXAxisBand($1.trim());}
|
||||
| AXIS_BAND_DATA_END
|
||||
;
|
||||
|
||||
parseYAxis
|
||||
: AXIS_TITLE {yy.setYAxisTitle($1.trim());}
|
||||
| AXIS_TITLE AXIS_RANGE_DATA {yy.setYAxisTitle($1.trim()); $$ = $2.split("-->"); yy.setYAxisRangeData(Number($$[0]), Number($$[1]));}
|
||||
;
|
||||
|
||||
directive
|
||||
: openDirective typeDirective closeDirective
|
||||
@ -115,7 +172,7 @@ argDirective
|
||||
;
|
||||
|
||||
closeDirective
|
||||
: close_directive { yy.parseDirective('}%%', 'close_directive', 'quadrantChart'); }
|
||||
: close_directive { yy.parseDirective('}%%', 'close_directive', 'xychart'); }
|
||||
;
|
||||
|
||||
text: alphaNumToken
|
||||
|
@ -0,0 +1,140 @@
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import { parser } from './xychart.jison';
|
||||
import { Mock, vi } from 'vitest';
|
||||
|
||||
const parserFnConstructor = (str: string) => {
|
||||
return () => {
|
||||
parser.parse(str);
|
||||
};
|
||||
};
|
||||
|
||||
const mockDB: Record<string, Mock<any, any>> = {
|
||||
parseDirective: vi.fn(),
|
||||
setOrientation: vi.fn(),
|
||||
setXAxisTitle: vi.fn(),
|
||||
setXAxisRangeData: vi.fn(),
|
||||
addXAxisBand: vi.fn(),
|
||||
setYAxisTitle: vi.fn(),
|
||||
setYAxisRangeData: vi.fn(),
|
||||
addYAxisBand: vi.fn(),
|
||||
};
|
||||
|
||||
function clearMocks() {
|
||||
for (const key in mockDB) {
|
||||
mockDB[key].mockRestore();
|
||||
}
|
||||
}
|
||||
|
||||
describe('Testing xychart jison file', () => {
|
||||
beforeEach(() => {
|
||||
parser.yy = mockDB;
|
||||
clearMocks();
|
||||
});
|
||||
|
||||
it('should throw error if xychart-beta text is not there', () => {
|
||||
const str = 'xychart-beta-1';
|
||||
expect(parserFnConstructor(str)).toThrow();
|
||||
});
|
||||
|
||||
it('should not throw error if only xychart is there', () => {
|
||||
const str = 'xychart-beta';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
});
|
||||
|
||||
it('should be able to parse directive', () => {
|
||||
const str =
|
||||
'%%{init: {"xychart": {"chartWidth": 600, "chartHeight": 600} } }%% \n xychart-beta';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.parseDirective.mock.calls[0]).toEqual(['%%{', 'open_directive']);
|
||||
expect(mockDB.parseDirective.mock.calls[1]).toEqual(['init', 'type_directive']);
|
||||
expect(mockDB.parseDirective.mock.calls[2]).toEqual([
|
||||
'{"xychart": {"chartWidth": 600, "chartHeight": 600} }',
|
||||
'arg_directive',
|
||||
]);
|
||||
expect(mockDB.parseDirective.mock.calls[3]).toEqual(['}%%', 'close_directive', 'xychart']);
|
||||
});
|
||||
|
||||
it('parse chart orientation', () => {
|
||||
let str = 'xychart-beta vertical';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setOrientation).toHaveBeenCalledWith('vertical');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta horizontal ';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setOrientation).toHaveBeenCalledWith('horizontal');
|
||||
|
||||
str = 'xychart-beta abc';
|
||||
expect(parserFnConstructor(str)).toThrow();
|
||||
});
|
||||
|
||||
it('parse x-axis', () => {
|
||||
let str = 'xychart-beta \nx-axis xAxisName\n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \nx-axis xAxisName \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \n x-axis "xAxisName has space"\n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName has space');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \n x-axis " xAxisName has space " \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName has space');
|
||||
|
||||
clearMocks();
|
||||
str = 'xychart-beta \nx-axis xAxisName 45.5 --> 33 \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName');
|
||||
expect(mockDB.setXAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \nx-axis xAxisName [ "cat1" , cat2 ] \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setXAxisTitle).toHaveBeenCalledWith('xAxisName');
|
||||
expect(mockDB.addXAxisBand).toHaveBeenCalledTimes(2);
|
||||
expect(mockDB.addXAxisBand).toHaveBeenNthCalledWith(1, "cat2");
|
||||
expect(mockDB.addXAxisBand).toHaveBeenNthCalledWith(2, "cat1");
|
||||
});
|
||||
it('parse y-axis', () => {
|
||||
let str = 'xychart-beta \ny-axis yAxisName\n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \ny-axis yAxisName \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \n y-axis "yAxisName has space"\n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName has space');
|
||||
|
||||
clearMocks();
|
||||
|
||||
str = 'xychart-beta \n y-axis " yAxisName has space " \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName has space');
|
||||
|
||||
clearMocks();
|
||||
str = 'xychart-beta \ny-axis yAxisName 45.5 --> 33 \n';
|
||||
expect(parserFnConstructor(str)).not.toThrow();
|
||||
expect(mockDB.setYAxisTitle).toHaveBeenCalledWith('yAxisName');
|
||||
expect(mockDB.setYAxisRangeData).toHaveBeenCalledWith(45.5, 33);
|
||||
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user