From f060f56c93a424b17d36851c544e5de83a04ceeb Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Wed, 28 Feb 2018 16:36:54 +0100 Subject: [PATCH] feat(complex-matcher): number comparison (#2702) `foo:>=42` matches `{ foo: 42 }` but not `"bar"` nor `{ foo: 37 }`. --- packages/complex-matcher/src/index.js | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/complex-matcher/src/index.js b/packages/complex-matcher/src/index.js index d540864a8..ba11bcc29 100644 --- a/packages/complex-matcher/src/index.js +++ b/packages/complex-matcher/src/index.js @@ -70,6 +70,29 @@ export class And extends Node { } } +export class Comparison extends Node { + constructor (operator, value) { + super() + this._comparator = Comparison.comparators[operator] + this._operator = operator + this._value = value + } + + match (value) { + return typeof value === 'number' && this._comparator(value, this._value) + } + + toString () { + return this._operator + String(this._value) + } +} +Comparison.comparators = { + '>': (a, b) => a > b, + '>=': (a, b) => a >= b, + '<': (a, b) => a < b, + '<=': (a, b) => a <= b, +} + export class Or extends Node { constructor (children) { super() @@ -408,6 +431,13 @@ const parser = P.grammar({ P.text(')') ).map(_ => new Or(_[4])), P.seq(P.text('!'), r.ws, r.term).map(_ => new Not(_[2])), + P.seq(P.regex(/[<>]=?/), r.rawString).map(([op, val]) => { + val = +val + if (Number.isNaN(val)) { + throw new TypeError('value must be a number') + } + return new Comparison(op, val) + }), P.seq(r.string, r.ws, P.text(':'), r.ws, r.term).map( _ => new Property(_[0], _[4]) ),