Commit cef4349b by Torkel Ödegaard

added lexer/parser support for templated metric expressions, karma test runner is working

parent 9480077f
......@@ -82,13 +82,24 @@ function (angular, _, config, graphiteFuncs, Parser) {
$scope.segments = _.map(astNode.segments, function(segment) {
return {
type: segment.type,
val: segment.value,
html: segment.value === '*' ? '<i class="icon-asterisk"><i>' : segment.value
html: getSegmentHtml(segment)
};
});
}
}
function getSegmentHtml(segment) {
if (segment.value === '*') {
return '<i class="icon-asterisk"><i>';
}
if (segment.type === 'template') {
return "<span style='color: #ECEC09'>[[" + segment.value + "]]</span>";
}
return segment.value;
}
function getSegmentPathUpTo(index) {
var arr = $scope.segments.slice(0, index);
......
......@@ -182,6 +182,7 @@ define([
match =
this.scanIdentifier() ||
this.scanTemplateSequence() ||
this.scanPunctuator() ||
this.scanNumericLiteral();
......@@ -194,6 +195,26 @@ define([
return null;
},
scanTemplateSequence: function() {
if (this.peek() === '[' && this.peek(1) === '[') {
return {
type: 'templateStart',
value: '[[',
pos: this.char
};
}
if (this.peek() === ']' && this.peek(1) === ']') {
return {
type: 'templateEnd',
value: '[[',
pos: this.char
};
}
return null;
},
/*
* Extract a JavaScript identifier out of the next sequence of
* characters or return 'null' if its not possible. In addition,
......
......@@ -29,29 +29,61 @@ define([
}
},
metricExpression: function() {
metricSegment: function() {
if (this.match('identifier')) {
this.index++;
return {
type: 'segment',
value: this.tokens[this.index-1].value
};
}
if (!this.match('templateStart')) {
this.errorMark('Expected metric identifier');
}
this.index++;
if (!this.match('identifier')) {
this.errorMark('Expected identifier after templateStart');
}
var node = {
type: 'template',
value: this.tokens[this.index].value
};
this.index++;
if (!this.match('templateEnd')) {
this.errorMark('Expected templateEnd');
}
this.index++;
return node;
},
metricExpression: function() {
if (!this.match('templateStart') && !this.match('identifier')) {
return null;
}
var node = {
type: 'metric',
segments: [{
type: 'segment',
value: this.tokens[this.index].value
}]
segments: []
};
this.index++;
node.segments.push(this.metricSegment());
if (this.match('.')) {
while(this.match('.')) {
this.index++;
var rest = this.metricExpression();
if (!rest) {
var segment = this.metricSegment();
if (!segment) {
this.errorMark('Expected metric identifier');
}
node.segments = node.segments.concat(rest.segments);
node.segments.push(segment);
}
return node;
......
module.exports = function(config) {
config.set({
basePath: '../',
frameworks: ['mocha', 'requirejs', 'expect'],
// list of files / patterns to load in the browser
files: [
'test/test-main.js',
{pattern: 'app/**/*.js', included: false},
{pattern: 'test/**/*.js', included: false}
],
// list of files to exclude
exclude: [
],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 60000,
singleRun: false
});
};
......@@ -30,6 +30,15 @@ define([
expect(tokens[tokens.length - 1].value).to.be(')');
});
it('should tokenize metric with template parameter', function() {
var lexer = new Lexer("metric.[[server]].test");
var tokens = lexer.tokenize();
expect(tokens[2].type).to.be('templateStart');
expect(tokens[3].type).to.be('identifier');
expect(tokens[3].value).to.be('server');
expect(tokens[4].type).to.be('templateEnd');
});
it('should handle error with unterminated string', function() {
var lexer = new Lexer("alias(metric, 'asd)");
var tokens = lexer.tokenize();
......
......@@ -54,6 +54,15 @@ define([
expect(rootNode.params[1].type).to.be('metric');
});
it('function with templated series', function() {
var parser = new Parser("sum(test.[[server]].count)");
var rootNode = parser.getAst();
expect(rootNode.message).to.be(undefined)
expect(rootNode.params[0].type).to.be('metric');
expect(rootNode.params[0].segments[1].type).to.be('template');
});
it('invalid metric expression', function() {
var parser = new Parser('metric.test.*.asd.');
var rootNode = parser.getAst();
......
require.config({
baseUrl:'base'
});
require([
'test/specs/lexer-specs',
'test/specs/parser-specs',
], function () {
window.__karma__.start();
});
\ No newline at end of file
module.exports = function(config) {
return {
unit: {
configFile: 'src/test/karma.conf.js',
singleRun: false,
browsers: ['Chrome']
}
};
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment