Skip to content

Instantly share code, notes, and snippets.

@moodmosaic
Last active August 29, 2015 14:00
Show Gist options
  • Save moodmosaic/11338753 to your computer and use it in GitHub Desktop.
Save moodmosaic/11338753 to your computer and use it in GitHub Desktop.
A small sample of a Jasmine custom matcher that internally parses expressions into an AST.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Custom matchers for Expressions</title>
<!-- $ bower install jasmine && npm install jsep -->
<link href="bower_components/jasmine/lib/jasmine-core/jasmine.css" rel="stylesheet" />
<script src="bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script src="bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script src="bower_components/jasmine/lib/jasmine-core/boot.js"></script>
<script src="node_modules/jsep/src/jsep.js"></script>
<script src="tests.js"></script>
</head>
<body>
</body>
</html>
var toHaveBeenCalledWithExpression = {
toHaveBeenCalledWithExpression: function () {
return {
compare: function () {
var createAbstractSyntaxTree = function (expression) {
return jsep(expression);
};
var binaryOperators = {
">": function (a, b) {
return a > b;
},
"<": function (a, b) {
return a < b;
},
"==": function (a, b) {
return a == b;
},
"===": function (a, b) {
return a === b;
},
"<=": function (a, b) {
return a <= b;
},
">=": function (a, b) {
return a >= b;
},
"!=": function (a, b) {
return a != b;
},
"!==": function (a, b) {
return a !== b;
}
};
var verify = function (type, operator, left, right) {
if (type === "BinaryExpression") {
return binaryOperators[operator](left, right);
}
};
var expression = arguments[1];
var leftComponent = arguments[0].calls.allArgs()[0][0];
var ast = createAbstractSyntaxTree(expression);
var result = verify(ast.type, ast.operator, leftComponent, ast.right.value);
return { pass: result };
}
};
}
};
describe('expectations via expressions parsed into an AST', function () {
beforeEach(function () {
jasmine.addMatchers(toHaveBeenCalledWithExpression);
});
[{
actual: 1,
expression: 'x > 0'
}, {
actual: 2,
expression: 'x < 3'
}, {
actual: 3,
expression: 'x == 3'
}, {
actual: 4,
expression: 'x === 4'
}, {
actual: 5,
expression: 'x <= 5'
}, {
actual: 6,
expression: 'x >= 6'
}, {
actual: 7,
expression: 'x != 8'
}, {
actual: 8,
expression: 'x !== 9'
}, {
actual: 1,
expression: 'y > 0'
}, {
actual: 2,
expression: 'y < 3'
}, {
actual: 3,
expression: 'y == 3'
}, {
actual: 4,
expression: 'y === 4'
}, {
actual: 5,
expression: 'y <= 5'
}, {
actual: 6,
expression: 'y >= 6'
}, {
actual: 7,
expression: 'y != 8'
}, {
actual: 8,
expression: 'y !== 9'
}, {
actual: 1,
expression: '_ > 0'
}, {
actual: 2,
expression: '_ < 3'
}, {
actual: 3,
expression: '_ == 3'
}, {
actual: 4,
expression: '_ === 4'
}, {
actual: 5,
expression: '_ <= 5'
}, {
actual: 6,
expression: '_ >= 6'
}, {
actual: 7,
expression: '_ != 8'
}, {
actual: 8,
expression: '_ !== 9'
}].forEach(function(testCase) {
var actual = testCase.actual;
var expression = testCase.expression;
it(actual + ' has been called with ' + expression, function() {
var sut = {};
sut.foo = function(arg) {};
spyOn(sut, 'foo');
sut.foo(actual);
expect(sut.foo).toHaveBeenCalledWithExpression(expression);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment