Comparing version 2.0.2 to 3.0.0
@@ -508,5 +508,150 @@ /** | ||
/** | ||
Visit each node in the qlobber's trie in turn. | ||
@return {Iterator} An iterator on the trie. The iterator returns objects which, if fed (in the same order) to the function returned by [`get_restorer`](#qlobberprototypeget_restoreroptions) on a different qlobber, will build that qlobber's trie to the same state. The objects can be serialized using `JSON.stringify`, _if_ the values you store in the qlobber are also serializable. | ||
*/ | ||
Qlobber.prototype.visit = function* () | ||
{ | ||
let iterators = [], | ||
iterator = this._trie.entries(), | ||
i = 0; | ||
while (true) | ||
{ | ||
if (i === 0) | ||
{ | ||
yield { type: 'start_entries' }; | ||
} | ||
let next = iterator.next(); | ||
if (next.done) | ||
{ | ||
yield { type: 'end_entries' }; | ||
let prev = iterators.pop(); | ||
if (prev === undefined) | ||
{ | ||
return; | ||
} | ||
[iterator, i] = prev; | ||
continue; | ||
} | ||
let [key, value] = next.value; | ||
yield { type: 'entry', i: i++, key: key }; | ||
if (key === this._separator) | ||
{ | ||
yield { type: 'start_values' }; | ||
if (value[Symbol.iterator]) | ||
{ | ||
let j = 0; | ||
for (let v of value) | ||
{ | ||
yield { type: 'value', i: j++, value: v }; | ||
} | ||
} | ||
else | ||
{ | ||
yield { type: 'value', i: 0, value: value }; | ||
} | ||
yield { type: 'end_values' }; | ||
continue; | ||
} | ||
iterators.push([iterator, i]); | ||
iterator = value.entries(); | ||
i = 0; | ||
} | ||
}; | ||
/** | ||
Get a function which can restore the qlobber's trie to a state you retrieved | ||
by calling [`visit`](#qlobberprototypevisit) on this or another qlobber. | ||
@param {Object} [options] Options for restoring the trie. | ||
- `{Boolean} cache_adds` Whether to cache topics when rebuilding the trie. This only applies if you also passed `cache_adds` as true in the [constructor](#qlobberoptions). | ||
@return {Function} Function to call in order to rebuild the qlobber's trie. You should call this repeatedly with the objects you received from a call to [`visit`](#qlobberprototypevisit). If you serialized the objects, remember to deserialize them first (e.g. with `JSON.parse`)! | ||
*/ | ||
Qlobber.prototype.get_restorer = function (options) | ||
{ | ||
options = options || {}; | ||
let sts = [], | ||
entry = this._trie, | ||
path = ''; | ||
return (obj) => | ||
{ | ||
switch (obj.type) | ||
{ | ||
case 'entry': | ||
entry = entry || new Map(); | ||
sts.push([entry, obj.key, path]); | ||
entry = entry.get(obj.key); | ||
if (options.cache_adds) | ||
{ | ||
if (path) | ||
{ | ||
path += this._separator; | ||
} | ||
path += obj.key; | ||
} | ||
break; | ||
case 'value': | ||
if (entry) | ||
{ | ||
this._add_value(entry, obj.value); | ||
} | ||
else | ||
{ | ||
entry = this._initial_value(obj.value); | ||
} | ||
break; | ||
case 'end_entries': | ||
if (entry && (entry.size === 0)) | ||
{ | ||
entry = undefined; | ||
} | ||
/* falls through */ | ||
case 'end_values': | ||
let prev = sts.pop(); | ||
if (prev === undefined) | ||
{ | ||
entry = undefined; | ||
path = ''; | ||
} | ||
else | ||
{ | ||
let [prev_entry, key, prev_path] = prev; | ||
if (entry) | ||
{ | ||
if (options.cache_adds && | ||
this._shortcuts && | ||
(obj.type === 'end_values')) | ||
{ | ||
this._shortcuts.set(prev_path, entry); | ||
} | ||
prev_entry.set(key, entry); | ||
} | ||
entry = prev_entry; | ||
path = prev_path; | ||
} | ||
break; | ||
} | ||
}; | ||
}; | ||
/** | ||
Creates a new de-duplicating qlobber. | ||
Inherits from Qlobber. | ||
Inherits from [`Qlobber`](#qlobberoptions). | ||
@@ -583,3 +728,3 @@ @constructor | ||
Inherits from Qlobber. | ||
Inherits from [`Qlobber`](#qlobberoptions). | ||
@@ -638,5 +783,72 @@ @constructor | ||
let stream = require('stream'); | ||
/** | ||
Creates a new [`Readable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_readable) stream, in object mode, which calls [`visit`](#qlobberprototypevisit) on a qlobber to generate its data. | ||
You could [`pipe`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_pipe_destination_options) this to a [`JSONStream.stringify`](https://github.com/dominictarr/JSONStream#jsonstreamstringifyopen-sep-close) stream, for instance, to serialize the qlobber to JSON. See [this test](test/json.js#L14) for an example. | ||
Inherits from [`Readable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_readable). | ||
@constructor | ||
@param {Qlobber} qlobber The qlobber to call [`visit`](#qlobberprototypevisit) on. | ||
*/ | ||
function VisitorStream (qlobber) | ||
{ | ||
stream.Readable.call(this, { objectMode: true }); | ||
this._iterator = qlobber.visit(); | ||
} | ||
util.inherits(VisitorStream, stream.Readable); | ||
VisitorStream.prototype._read = function () | ||
{ | ||
while (true) | ||
{ | ||
let { done, value } = this._iterator.next(); | ||
if (done) | ||
{ | ||
this.push(null); | ||
break; | ||
} | ||
if (!this.push(value)) | ||
{ | ||
break; | ||
} | ||
} | ||
}; | ||
/** | ||
Creates a new [`Writable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_writable) stream, in object mode, which passes data written to it into the function returned by calling [`get_restorer`](#qlobberprototypeget_restoreroptions) on a qlobber. | ||
You could [`pipe`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_pipe_destination_options) a [`JSONStream.parse`](https://github.com/dominictarr/JSONStream#jsonstreamparsepath) stream to this, for instance, to deserialize the qlobber from JSON. See [this test](test/json.js#L33) for an example. | ||
Inherits from [`Writable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_writable). | ||
@constructor | ||
@param {Qlobber} qlobber The qlobber to call [`get_restorer`](#qlobberprototypeget_restoreroptions) on. | ||
*/ | ||
function RestorerStream (qlobber) | ||
{ | ||
stream.Writable.call(this, { objectMode: true }); | ||
this._restorer = qlobber.get_restorer(); | ||
} | ||
util.inherits(RestorerStream, stream.Writable); | ||
RestorerStream.prototype._write = function (value, _, cb) | ||
{ | ||
this._restorer(value); | ||
cb(); | ||
}; | ||
exports.Qlobber = Qlobber; | ||
exports.QlobberDedup = QlobberDedup; | ||
exports.QlobberTrue = QlobberTrue; | ||
exports.VisitorStream = VisitorStream; | ||
exports.RestorerStream = RestorerStream; | ||
{ | ||
"name": "qlobber", | ||
"description": "Node.js globbing for amqp-like topics", | ||
"version": "2.0.2", | ||
"version": "3.0.0", | ||
"homepage": "https://github.com/davedoesdev/qlobber", | ||
@@ -36,3 +36,3 @@ "author": { | ||
"engines": { | ||
"node": ">= 4" | ||
"node": ">= 6" | ||
}, | ||
@@ -49,4 +49,6 @@ "devDependencies": { | ||
"coveralls": "~3.0.0", | ||
"b": "git://github.com/davedoesdev/b.git" | ||
"b": "git://github.com/davedoesdev/b.git", | ||
"JSONStream": "~1.3.2", | ||
"stream-buffers": "~3.0.1" | ||
} | ||
} |
@@ -108,2 +108,4 @@ # qlobber [![Build Status](https://travis-ci.org/davedoesdev/qlobber.png)](https://travis-ci.org/davedoesdev/qlobber) [![Coverage Status](https://coveralls.io/repos/davedoesdev/qlobber/badge.png?branch=master)](https://coveralls.io/r/davedoesdev/qlobber?branch=master) [![NPM version](https://badge.fury.io/js/qlobber.png)](http://badge.fury.io/js/qlobber) | ||
- <a name="toc_qlobberprototypeclear"></a>[Qlobber.prototype.clear](#qlobberprototypeclear) | ||
- <a name="toc_qlobberprototypevisit"></a>[Qlobber.prototype.visit](#qlobberprototypevisit) | ||
- <a name="toc_qlobberprototypeget_restoreroptions"></a>[Qlobber.prototype.get_restorer](#qlobberprototypeget_restoreroptions) | ||
- <a name="toc_qlobberdedupoptions"></a>[QlobberDedup](#qlobberdedupoptions) | ||
@@ -115,2 +117,4 @@ - <a name="toc_qlobberdedupprototypetest_valuesvals-val"></a><a name="toc_qlobberdedupprototype"></a>[QlobberDedup.prototype.test_values](#qlobberdedupprototypetest_valuesvals-val) | ||
- <a name="toc_qlobbertrueprototypematchtopic"></a>[QlobberTrue.prototype.match](#qlobbertrueprototypematchtopic) | ||
- <a name="toc_visitorstreamqlobber"></a>[VisitorStream](#visitorstreamqlobber) | ||
- <a name="toc_restorerstreamqlobber"></a>[RestorerStream](#restorerstreamqlobber) | ||
@@ -224,2 +228,28 @@ ## Qlobber([options]) | ||
## Qlobber.prototype.visit() | ||
> Visit each node in the qlobber's trie in turn. | ||
**Return:** | ||
`{Iterator}` An iterator on the trie. The iterator returns objects which, if fed (in the same order) to the function returned by [`get_restorer`](#qlobberprototypeget_restoreroptions) on a different qlobber, will build that qlobber's trie to the same state. The objects can be serialized using `JSON.stringify`, _if_ the values you store in the qlobber are also serializable. | ||
<sub>Go: [TOC](#tableofcontents) | [Qlobber.prototype](#toc_qlobberprototype)</sub> | ||
## Qlobber.prototype.get_restorer([options]) | ||
> Get a function which can restore the qlobber's trie to a state you retrieved | ||
by calling [`visit`](#qlobberprototypevisit) on this or another qlobber. | ||
**Parameters:** | ||
- `{Object} [options]` Options for restoring the trie. | ||
- `{Boolean} cache_adds` Whether to cache topics when rebuilding the trie. This only applies if you also passed `cache_adds` as true in the [constructor](#qlobberoptions). | ||
**Return:** | ||
`{Function}` Function to call in order to rebuild the qlobber's trie. You should call this repeatedly with the objects you received from a call to [`visit`](#qlobberprototypevisit). If you serialized the objects, remember to deserialize them first (e.g. with `JSON.parse`)! | ||
<sub>Go: [TOC](#tableofcontents) | [Qlobber.prototype](#toc_qlobberprototype)</sub> | ||
## QlobberDedup([options]) | ||
@@ -229,3 +259,3 @@ | ||
Inherits from [Qlobber](#qlobberoptions). | ||
Inherits from [`Qlobber`](#qlobberoptions). | ||
@@ -278,3 +308,3 @@ **Parameters:** | ||
Inherits from [Qlobber](#qlobberoptions). | ||
Inherits from [`Qlobber`](#qlobberoptions). | ||
@@ -320,2 +350,30 @@ **Parameters:** | ||
## VisitorStream(qlobber) | ||
> Creates a new [`Readable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_readable) stream, in object mode, which calls [`visit`](#qlobberprototypevisit) on a qlobber to generate its data. | ||
You could [`pipe`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_pipe_destination_options) this to a [`JSONStream.stringify`](https://github.com/dominictarr/JSONStream#jsonstreamstringifyopen-sep-close) stream, for instance, to serialize the qlobber to JSON. See [this test](test/json.js#L14) for an example. | ||
Inherits from [`Readable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_readable). | ||
**Parameters:** | ||
- `{Qlobber} qlobber` The qlobber to call [`visit`](#qlobberprototypevisit) on. | ||
<sub>Go: [TOC](#tableofcontents)</sub> | ||
## RestorerStream(qlobber) | ||
> Creates a new [`Writable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_writable) stream, in object mode, which passes data written to it into the function returned by calling [`get_restorer`](#qlobberprototypeget_restoreroptions) on a qlobber. | ||
You could [`pipe`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_pipe_destination_options) a [`JSONStream.parse`](https://github.com/dominictarr/JSONStream#jsonstreamparsepath) stream to this, for instance, to deserialize the qlobber from JSON. See [this test](test/json.js#L33) for an example. | ||
Inherits from [`Writable`](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_class_stream_writable). | ||
**Parameters:** | ||
- `{Qlobber} qlobber` The qlobber to call [`get_restorer`](#qlobberprototypeget_restoreroptions) on. | ||
<sub>Go: [TOC](#tableofcontents)</sub> | ||
_—generated by [apidox](https://github.com/codeactual/apidox)—_ |
@@ -14,3 +14,4 @@ /*globals rabbitmq_test_bindings : false, | ||
var expect = require('chai').expect, | ||
qlobber = require('..'); | ||
qlobber = require('..'), | ||
common = require('./common'); | ||
@@ -27,15 +28,2 @@ describe('qlobber-dedup', function () | ||
if (Array.from === undefined) | ||
{ | ||
Array.from = function (s) | ||
{ | ||
var a = []; | ||
s.forEach(function (v) | ||
{ | ||
a[a.length] = v; | ||
}); | ||
return a; | ||
}; | ||
} | ||
function add_bindings(bindings, mapper) | ||
@@ -51,25 +39,6 @@ { | ||
function get_trie(matcher, t) | ||
{ | ||
t = t || matcher.get_trie(); | ||
var k, r = {}; | ||
for (k of t.keys()) | ||
{ | ||
if (k === '.') | ||
{ | ||
r[k] = Array.from(t.get(k)); | ||
} | ||
else | ||
{ | ||
r[k] = get_trie(matcher, t.get(k)); | ||
} | ||
} | ||
return r; | ||
} | ||
it('should support adding bindings', function () | ||
{ | ||
add_bindings(rabbitmq_test_bindings); | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t1","t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},".":["t11"],"#":{".":["t12"]}}},"#":{".":["t5"],"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{".":["t21"],"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]},"vodka":{"martini":{".":["t19"]}}}); | ||
expect(common.get_trie(matcher)).to.eql(common.expected_trie); | ||
}); | ||
@@ -103,3 +72,3 @@ | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
expect(common.get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
@@ -170,3 +139,3 @@ rabbitmq_expected_results_after_remove.forEach(function (test) | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
expect(common.get_trie(matcher)).to.eql({"a":{"b":{"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
@@ -315,3 +284,3 @@ rabbitmq_expected_results_after_remove_all.forEach(function (test) | ||
matcher.add('a.*', 'foo'); | ||
expect(get_trie(matcher)).to.eql({ a: { b: { '.': ['foo'] }, '*': { '.': ['foo'] } } }); | ||
expect(common.get_trie(matcher)).to.eql({ a: { b: { '.': ['foo'] }, '*': { '.': ['foo'] } } }); | ||
expect(Array.from(matcher.match('a.b'))).to.eql(['foo']); | ||
@@ -344,3 +313,39 @@ expect(matcher.test('a.b', 'foo')).to.equal(true); | ||
}); | ||
it('should visit trie', function () | ||
{ | ||
add_bindings(rabbitmq_test_bindings); | ||
let objs = []; | ||
for (let v of matcher.visit()) | ||
{ | ||
objs.push(v); | ||
} | ||
expect(objs).to.eql(common.expected_visits); | ||
}); | ||
it('should restore trie', function () | ||
{ | ||
let restorer = matcher.get_restorer(); | ||
for (let v of common.expected_visits) | ||
{ | ||
restorer(v); | ||
} | ||
expect(common.get_trie(matcher)).to.eql(common.expected_trie); | ||
rabbitmq_expected_results_before_remove.forEach(function (test) | ||
{ | ||
expect(Array.from(matcher.match(test[0])).sort(), test[0]).to.eql( | ||
test[1].sort()); | ||
for (var v of test[1]) | ||
{ | ||
expect(matcher.test(test[0], v)).to.equal(true); | ||
} | ||
expect(matcher.test(test[0], 'xyzfoo')).to.equal(false); | ||
}); | ||
}); | ||
}); | ||
@@ -100,1 +100,3 @@ /*globals global */ | ||
]; | ||
exports.test_bindings = global.rabbitmq_test_bindings; |
@@ -14,3 +14,4 @@ /*globals rabbitmq_test_bindings : false, | ||
var expect = require('chai').expect, | ||
qlobber = require('..'); | ||
qlobber = require('..'), | ||
common = require('./common'); | ||
@@ -47,16 +48,8 @@ describe('qlobber', function () | ||
function get_trie(matcher, t) | ||
function get_shortcuts(matcher) | ||
{ | ||
t = t || matcher.get_trie(); | ||
var k, r = {}; | ||
for (k of t.keys()) | ||
for (k of matcher._shortcuts.keys()) | ||
{ | ||
if (k === '.') | ||
{ | ||
r[k] = t.get(k); | ||
} | ||
else | ||
{ | ||
r[k] = get_trie(matcher, t.get(k)); | ||
} | ||
r[k] = matcher._shortcuts.get(k); | ||
} | ||
@@ -69,4 +62,3 @@ return r; | ||
add_bindings(rabbitmq_test_bindings); | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t1","t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},".":["t11"],"#":{".":["t12"]}}},"#":{".":["t5"],"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{".":["t21"],"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]},"vodka":{"martini":{".":["t19"]}}}); | ||
expect(common.get_trie(matcher)).to.eql(common.expected_trie); | ||
}); | ||
@@ -99,3 +91,3 @@ | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
expect(common.get_trie(matcher)).to.eql({"a":{"b":{"c":{".":["t20"]},"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
@@ -163,3 +155,3 @@ rabbitmq_expected_results_after_remove.forEach(function (test) | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
expect(common.get_trie(matcher)).to.eql({"a":{"b":{"b":{"c":{".":["t4"]},".":["t14"]},".":["t15"]},"*":{"c":{".":["t2"]},".":["t9"]},"#":{"b":{".":["t3"]},"#":{".":["t12"]}}},"#":{"#":{".":["t6"],"#":{".":["t24"]}},"b":{".":["t7"],"#":{".":["t26"]}},"*":{"#":{".":["t22"]}}},"*":{"*":{".":["t8"],"*":{".":["t18"]}},"b":{"c":{".":["t10"]}},"#":{"#":{".":["t23"]}},".":["t25"]},"b":{"b":{"c":{".":["t13"]}},"c":{".":["t16"]}},"":{".":["t17"]}}); | ||
@@ -231,3 +223,3 @@ rabbitmq_expected_results_after_remove_all.forEach(function (test) | ||
expect(matcher.match('foo.bar')).to.eql(['it matched!']); | ||
expect(matcher.test('foo.bar', 'it matched!')).to.equal(true); | ||
expect(matcher.test('foo.bar', 'it matched!')).to.equal(true); | ||
}); | ||
@@ -237,3 +229,3 @@ | ||
{ | ||
matcher.add('*.orange.*', 'Q1'); | ||
matcher.add('*.orange.*', 'Q1'); | ||
matcher.add('*.*.rabbit', 'Q2'); | ||
@@ -252,4 +244,4 @@ matcher.add('lazy.#', 'Q2'); | ||
return [matcher.match(topic).sort(), | ||
matcher.test(topic, 'Q1'), | ||
matcher.test(topic, 'Q2')]; | ||
matcher.test(topic, 'Q1'), | ||
matcher.test(topic, 'Q2')]; | ||
})).to.eql( | ||
@@ -330,3 +322,136 @@ [[['Q1', 'Q2'], true, true], | ||
}); | ||
it('should visit trie', function () | ||
{ | ||
add_bindings(rabbitmq_test_bindings); | ||
let objs = []; | ||
for (let v of matcher.visit()) | ||
{ | ||
objs.push(v); | ||
} | ||
expect(objs).to.eql(common.expected_visits); | ||
}); | ||
it('should restore trie', function () | ||
{ | ||
let restorer = matcher.get_restorer(); | ||
for (let v of common.expected_visits) | ||
{ | ||
restorer(v); | ||
} | ||
expect(common.get_trie(matcher)).to.eql(common.expected_trie); | ||
rabbitmq_expected_results_before_remove.forEach(function (test) | ||
{ | ||
expect(matcher.match(test[0]).remove_duplicates(), test[0]).to.eql(test[1].sort()); | ||
for (var v of test[1]) | ||
{ | ||
expect(matcher.test(test[0], v)).to.equal(true); | ||
} | ||
expect(matcher.test(test[0], 'xyzfoo')).to.equal(false); | ||
}); | ||
}); | ||
it('should not restore empty entries', function () | ||
{ | ||
matcher.add('foo.bar', 90); | ||
matcher._trie.get('foo').get('bar').get('.').shift(); | ||
let objs = []; | ||
for (let v of matcher.visit()) | ||
{ | ||
objs.push(v); | ||
} | ||
expect(objs).to.eql([ | ||
{ type: 'start_entries' }, | ||
{ type: 'entry', i: 0, key: 'foo' }, | ||
{ type: 'start_entries' }, | ||
{ type: 'entry', i: 0, key: 'bar' }, | ||
{ type: 'start_entries' }, | ||
{ type: 'entry', i: 0, key: '.' }, | ||
{ type: 'start_values' }, | ||
{ type: 'end_values' }, | ||
{ type: 'end_entries' }, | ||
{ type: 'end_entries' }, | ||
{ type: 'end_entries' } | ||
]); | ||
let matcher2 = new qlobber.Qlobber(), | ||
restorer = matcher2.get_restorer(); | ||
for (let v of objs) | ||
{ | ||
restorer(v); | ||
} | ||
expect(common.get_trie(matcher2)).to.eql({}); | ||
expect(matcher2.match('foo.bar')).to.eql([]); | ||
expect(matcher2.test('foo.bar', 90)).to.equal(false); | ||
}); | ||
it('should restore shortcuts', function () | ||
{ | ||
matcher = new qlobber.Qlobber({ cache_adds: true }); | ||
add_bindings(rabbitmq_test_bindings); | ||
let shortcuts = get_shortcuts(matcher); | ||
expect(shortcuts).to.eql({ | ||
'a.b.c': [ 't1', 't20' ], | ||
'a.*.c': [ 't2' ], | ||
'a.#.b': [ 't3' ], | ||
'a.b.b.c': [ 't4' ], | ||
'#': [ 't5' ], | ||
'#.#': [ 't6' ], | ||
'#.b': [ 't7' ], | ||
'*.*': [ 't8' ], | ||
'a.*': [ 't9' ], | ||
'*.b.c': [ 't10' ], | ||
'a.#': [ 't11' ], | ||
'a.#.#': [ 't12' ], | ||
'b.b.c': [ 't13' ], | ||
'a.b.b': [ 't14' ], | ||
'a.b': [ 't15' ], | ||
'b.c': [ 't16' ], | ||
'': [ 't17' ], | ||
'*.*.*': [ 't18' ], | ||
'vodka.martini': [ 't19' ], | ||
'*.#': [ 't21' ], | ||
'#.*.#': [ 't22' ], | ||
'*.#.#': [ 't23' ], | ||
'#.#.#': [ 't24' ], | ||
'*': [ 't25' ], | ||
'#.b.#': [ 't26' ] | ||
}); | ||
let objs = []; | ||
for (let v of matcher.visit()) | ||
{ | ||
objs.push(v); | ||
} | ||
expect(objs).to.eql(common.expected_visits); | ||
let matcher2 = new qlobber.Qlobber({ cache_adds: true }), | ||
restorer = matcher2.get_restorer(); | ||
for (let v of common.expected_visits) | ||
{ | ||
restorer(v); | ||
} | ||
expect(get_shortcuts(matcher2)).to.eql({}); | ||
matcher2 = new qlobber.Qlobber({ cache_adds: true }); | ||
restorer = matcher2.get_restorer({ cache_adds: true }); | ||
for (let v of common.expected_visits) | ||
{ | ||
restorer(v); | ||
} | ||
expect(get_shortcuts(matcher2)).to.eql(shortcuts); | ||
}); | ||
}); | ||
@@ -0,1 +1,3 @@ | ||
/*globals rabbitmq_test_bindings: false, | ||
rabbitmq_expected_results_before_remove: false */ | ||
/*jshint node: true, mocha: true */ | ||
@@ -6,3 +8,4 @@ "use strict"; | ||
qlobber = require('..'), | ||
QlobberTrue = qlobber.QlobberTrue; | ||
QlobberTrue = qlobber.QlobberTrue, | ||
expected_visits = require('./common').expected_true_visits; | ||
@@ -57,2 +60,71 @@ describe('true', function () | ||
}); | ||
function add_bindings(matcher, bindings, mapper) | ||
{ | ||
mapper = mapper || function (topic) { return topic; }; | ||
bindings.forEach(function (topic_val) | ||
{ | ||
matcher.add(topic_val[0], mapper(topic_val[1])); | ||
}); | ||
} | ||
function get_trie(matcher, t) | ||
{ | ||
t = t || matcher.get_trie(); | ||
var k, r = {}; | ||
for (k of t.keys()) | ||
{ | ||
if (k === '.') | ||
{ | ||
r[k] = t.get(k); | ||
} | ||
else | ||
{ | ||
r[k] = get_trie(matcher, t.get(k)); | ||
} | ||
} | ||
return r; | ||
} | ||
it('should visit trie', function () | ||
{ | ||
let matcher = new QlobberTrue(); | ||
add_bindings(matcher, rabbitmq_test_bindings); | ||
let objs = []; | ||
for (let v of matcher.visit()) | ||
{ | ||
objs.push(v); | ||
} | ||
expect(objs).to.eql(expected_visits); | ||
}); | ||
it('should restore trie', function () | ||
{ | ||
let matcher = new QlobberTrue(), | ||
restorer = matcher.get_restorer(); | ||
for (let v of expected_visits) | ||
{ | ||
restorer(v); | ||
} | ||
expect(get_trie(matcher)).to.eql({"a":{"b":{"c":{".":true},"b":{"c":{".":true},".":true},".":true},"*":{"c":{".":true},".":true},"#":{"b":{".":true},".":true,"#":{".":true}}},"#":{".":true,"#":{".":true,"#":{".":true}},"b":{".":true,"#":{".":true}},"*":{"#":{".":true}}},"*":{"*":{".":true,"*":{".":true}},"b":{"c":{".":true}},"#":{".":true,"#":{".":true}},".":true},"b":{"b":{"c":{".":true}},"c":{".":true}},"":{".":true},"vodka":{"martini":{".":true}}}); | ||
rabbitmq_expected_results_before_remove.forEach(function (test) | ||
{ | ||
expect(matcher.match(test[0]), test[0]).to.equal(true); | ||
for (var v of test[1]) | ||
{ | ||
expect(matcher.test(test[0], v)).to.equal(true); | ||
} | ||
expect(matcher.test(test[0], 'xyzfoo')).to.equal(true); | ||
}); | ||
expect(matcher.match('xyzfoo')).to.equal(true); | ||
expect(matcher.test('xyzfoo')).to.equal(true); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
294450
55
3842
374
12