Add comprehensive development roadmap via GitHub Issues

Created 10 detailed GitHub issues covering:
- Project activation and management UI (#1-2)
- Worker node coordination and visualization (#3-4)
- Automated GitHub repository scanning (#5)
- Intelligent model-to-issue matching (#6)
- Multi-model task execution system (#7)
- N8N workflow integration (#8)
- Hive-Bzzz P2P bridge (#9)
- Peer assistance protocol (#10)

Each issue includes detailed specifications, acceptance criteria,
technical implementation notes, and dependency mapping.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-07-12 19:41:01 +10:00
parent 9a6a06da89
commit e89f2f4b7b
4980 changed files with 1501266 additions and 57 deletions

225
mcp-server/node_modules/lunr/test/builder_test.js generated vendored Normal file
View File

@@ -0,0 +1,225 @@
suite('lunr.Builder', function () {
suite('#add', function () {
setup(function () {
this.builder = new lunr.Builder
})
test('field contains terms that clash with object prototype', function () {
this.builder.field('title')
this.builder.add({ id: 'id', title: 'constructor'})
assert.deepProperty(this.builder.invertedIndex, 'constructor.title.id')
assert.deepEqual(this.builder.invertedIndex.constructor.title.id, {})
assert.equal(this.builder.fieldTermFrequencies['title/id'].constructor, 1)
})
test('field name clashes with object prototype', function () {
this.builder.field('constructor')
this.builder.add({ id: 'id', constructor: 'constructor'})
assert.deepProperty(this.builder.invertedIndex, 'constructor.constructor.id')
assert.deepEqual(this.builder.invertedIndex.constructor.constructor.id, {})
})
test('document ref clashes with object prototype', function () {
this.builder.field('title')
this.builder.add({ id: 'constructor', title: 'word'})
assert.deepProperty(this.builder.invertedIndex, 'word.title.constructor')
assert.deepEqual(this.builder.invertedIndex.word.title.constructor, {})
})
test('token metadata clashes with object prototype', function () {
var pipelineFunction = function (t) {
t.metadata['constructor'] = 'foo'
return t
}
lunr.Pipeline.registerFunction(pipelineFunction, 'test')
this.builder.pipeline.add(pipelineFunction)
// the registeredFunctions object is global, this is to prevent
// polluting any other tests.
delete lunr.Pipeline.registeredFunctions.test
this.builder.metadataWhitelist.push('constructor')
this.builder.field('title')
this.builder.add({ id: 'id', title: 'word'})
assert.deepProperty(this.builder.invertedIndex, 'word.title.id.constructor')
assert.deepEqual(this.builder.invertedIndex.word.title.id.constructor, ['foo'])
})
test('extracting nested properties from a document', function () {
var extractor = function (d) { return d.person.name }
this.builder.field('name', {
extractor: extractor
})
this.builder.add({
id: 'id',
person: {
name: 'bob'
}
})
assert.deepProperty(this.builder.invertedIndex, 'bob.name.id')
})
})
suite('#field', function () {
test('defining fields to index', function () {
var builder = new lunr.Builder
builder.field('foo')
assert.property(builder._fields, 'foo')
})
test('field with illegal characters', function () {
var builder = new lunr.Builder
assert.throws(function () {
builder.field('foo/bar')
})
})
})
suite('#ref', function () {
test('default reference', function () {
var builder = new lunr.Builder
assert.equal('id', builder._ref)
})
test('defining a reference field', function () {
var builder = new lunr.Builder
builder.ref('foo')
assert.equal('foo', builder._ref)
})
})
suite('#b', function () {
test('default value', function () {
var builder = new lunr.Builder
assert.equal(0.75, builder._b)
})
test('values less than zero', function () {
var builder = new lunr.Builder
builder.b(-1)
assert.equal(0, builder._b)
})
test('values higher than one', function () {
var builder = new lunr.Builder
builder.b(1.5)
assert.equal(1, builder._b)
})
test('value within range', function () {
var builder = new lunr.Builder
builder.b(0.5)
assert.equal(0.5, builder._b)
})
})
suite('#k1', function () {
test('default value', function () {
var builder = new lunr.Builder
assert.equal(1.2, builder._k1)
})
test('values less than zero', function () {
var builder = new lunr.Builder
builder.k1(1.6)
assert.equal(1.6, builder._k1)
})
})
suite('#use', function () {
setup(function () {
this.builder = new lunr.Builder
})
test('calls plugin function', function () {
var wasCalled = false,
plugin = function () { wasCalled = true }
this.builder.use(plugin)
assert.isTrue(wasCalled)
})
test('sets context to the builder instance', function () {
var context = null,
plugin = function () { context = this }
this.builder.use(plugin)
assert.equal(context, this.builder)
})
test('passes builder as first argument', function () {
var arg = null,
plugin = function (a) { arg = a }
this.builder.use(plugin)
assert.equal(arg, this.builder)
})
test('forwards arguments to the plugin', function () {
var args = null,
plugin = function () { args = [].slice.call(arguments) }
this.builder.use(plugin, 1, 2, 3)
assert.deepEqual(args, [this.builder, 1, 2, 3])
})
})
suite('#build', function () {
setup(function () {
var builder = new lunr.Builder,
doc = { id: 'id', title: 'test', body: 'missing' }
builder.ref('id')
builder.field('title')
builder.add(doc)
builder.build()
this.builder = builder
})
test('adds tokens to invertedIndex', function () {
assert.deepProperty(this.builder.invertedIndex, 'test.title.id')
})
test('builds a vector space of the document fields', function () {
assert.property(this.builder.fieldVectors, 'title/id')
assert.instanceOf(this.builder.fieldVectors['title/id'], lunr.Vector)
})
test('skips fields not defined for indexing', function () {
assert.notProperty(this.builder.invertedIndex, 'missing')
})
test('builds a token set for the corpus', function () {
var needle = lunr.TokenSet.fromString('test')
assert.include(this.builder.tokenSet.intersect(needle).toArray(), 'test')
})
test('calculates document count', function () {
assert.equal(1, this.builder.documentCount)
})
test('calculates average field length', function () {
assert.equal(1, this.builder.averageFieldLength['title'])
})
test('index returned', function () {
var builder = new lunr.Builder,
doc = { id: 'id', title: 'test', body: 'missing' }
builder.ref('id')
builder.field('title')
builder.add(doc)
assert.instanceOf(builder.build(), lunr.Index)
})
})
})

6142
mcp-server/node_modules/lunr/test/env/chai.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

43
mcp-server/node_modules/lunr/test/env/index.mustache generated vendored Normal file
View File

@@ -0,0 +1,43 @@
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="/test/env/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script src="/test/env/mocha.js"></script>
<script src="/test/env/chai.js"></script>
<script src="/lunr.js"></script>
<script>
mocha.setup('tdd')
window.assert = chai.assert
window.withFixture = function (name, fn) {
var fixturePath = '/test/fixtures/' + name,
xhr = new XMLHttpRequest
xhr.addEventListener('load', function () {
if (this.status != 200) {
fn('non 200 response')
} else {
fn(null, this.responseText)
}
})
xhr.open('GET', fixturePath)
xhr.send()
}
</script>
{{#test_files}}
<script src="/{{{.}}}"></script>
{{/test_files}}
<script>
mocha.checkLeaks();
mocha.globals(['lunr']);
mocha.run();
</script>
</body>
</html>

326
mcp-server/node_modules/lunr/test/env/mocha.css generated vendored Normal file
View File

@@ -0,0 +1,326 @@
@charset "utf-8";
body {
margin:0;
}
#mocha {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 60px 50px;
}
#mocha ul,
#mocha li {
margin: 0;
padding: 0;
}
#mocha ul {
list-style: none;
}
#mocha h1,
#mocha h2 {
margin: 0;
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha h1 a {
text-decoration: none;
color: inherit;
}
#mocha h1 a:hover {
text-decoration: underline;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}
#mocha .hidden {
display: none;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
overflow: hidden;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial, sans-serif;
}
#mocha .test.pass.medium .duration {
background: #c09853;
}
#mocha .test.pass.slow .duration {
background: #b94a48;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00d6b2;
}
#mocha .test.pass .duration {
font-size: 9px;
margin-left: 5px;
padding: 2px 5px;
color: #fff;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#mocha .test.pass.fast .duration {
display: none;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
max-height: 300px;
overflow: auto;
}
#mocha .test .html-error {
overflow: auto;
color: black;
line-height: 1.5;
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: -webkit-calc(100% - 42px);
max-width: -moz-calc(100% - 42px);
max-width: calc(100% - 42px); /*(2)*/
max-height: 300px;
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-box-shadow: 0 1px 3px #eee;
box-shadow: 0 1px 3px #eee;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
#mocha .test .html-error pre.error {
border: none;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: 0;
-moz-box-shadow: 0;
box-shadow: 0;
padding: 0;
margin: 0;
margin-top: 18px;
max-height: none;
}
/**
* (1): approximate for browsers not supporting calc
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
* ^^ seriously
*/
#mocha .test pre {
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: -webkit-calc(100% - 42px);
max-width: -moz-calc(100% - 42px);
max-width: calc(100% - 42px); /*(2)*/
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-box-shadow: 0 1px 3px #eee;
box-shadow: 0 1px 3px #eee;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
#mocha .test h2 {
position: relative;
}
#mocha .test a.replay {
position: absolute;
top: 3px;
right: 0;
text-decoration: none;
vertical-align: middle;
display: block;
width: 15px;
height: 15px;
line-height: 15px;
text-align: center;
background: #eee;
font-size: 15px;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
-webkit-transition:opacity 200ms;
-moz-transition:opacity 200ms;
-o-transition:opacity 200ms;
transition: opacity 200ms;
opacity: 0.3;
color: #888;
}
#mocha .test:hover a.replay {
opacity: 1;
}
#mocha-report.pass .test.fail {
display: none;
}
#mocha-report.fail .test.pass {
display: none;
}
#mocha-report.pending .test.pass,
#mocha-report.pending .test.fail {
display: none;
}
#mocha-report.pending .test.pass.pending {
display: block;
}
#mocha-error {
color: #c00;
font-size: 1.5em;
font-weight: 100;
letter-spacing: 1px;
}
#mocha-stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
z-index: 1;
}
#mocha-stats .progress {
float: right;
padding-top: 0;
/**
* Set safe initial values, so mochas .progress does not inherit these
* properties from Bootstrap .progress (which causes .progress height to
* equal line height set in Bootstrap).
*/
height: auto;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
background-color: initial;
}
#mocha-stats em {
color: black;
}
#mocha-stats a {
text-decoration: none;
color: inherit;
}
#mocha-stats a:hover {
border-bottom: 1px solid #eee;
}
#mocha-stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
#mocha-stats canvas {
width: 40px;
height: 40px;
}
#mocha code .comment { color: #ddd; }
#mocha code .init { color: #2f6fad; }
#mocha code .string { color: #5890ad; }
#mocha code .keyword { color: #8a6343; }
#mocha code .number { color: #2f6fad; }
@media screen and (max-device-width: 480px) {
#mocha {
margin: 60px 0px;
}
#mocha #stats {
position: absolute;
}
}

15174
mcp-server/node_modules/lunr/test/env/mocha.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

35
mcp-server/node_modules/lunr/test/field_ref_test.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
suite('lunr.FieldRef', function () {
suite('#toString', function () {
test('combines document ref and field name', function () {
var fieldName = "title",
documentRef = "123",
fieldRef = new lunr.FieldRef (documentRef, fieldName)
assert.equal(fieldRef.toString(), "title/123")
})
})
suite('.fromString', function () {
test('splits string into parts', function () {
var fieldRef = lunr.FieldRef.fromString("title/123")
assert.equal(fieldRef.fieldName, "title")
assert.equal(fieldRef.docRef, "123")
})
test('docRef contains join character', function () {
var fieldRef = lunr.FieldRef.fromString("title/http://example.com/123")
assert.equal(fieldRef.fieldName, "title")
assert.equal(fieldRef.docRef, "http://example.com/123")
})
test('string does not contain join character', function () {
var s = "docRefOnly"
assert.throws(function () {
lunr.FieldRef.fromString(s)
})
})
})
})

View File

@@ -0,0 +1 @@
{"consign":"consign","consigned":"consign","consigning":"consign","consignment":"consign","consist":"consist","consisted":"consist","consistency":"consist","consistent":"consist","consistently":"consist","consisting":"consist","consists":"consist","consolation":"consol","consolations":"consol","consolatory":"consolatori","console":"consol","consoled":"consol","consoles":"consol","consolidate":"consolid","consolidated":"consolid","consolidating":"consolid","consoling":"consol","consols":"consol","consonant":"conson","consort":"consort","consorted":"consort","consorting":"consort","conspicuous":"conspicu","conspicuously":"conspicu","conspiracy":"conspiraci","conspirator":"conspir","conspirators":"conspir","conspire":"conspir","conspired":"conspir","conspiring":"conspir","constable":"constabl","constables":"constabl","constance":"constanc","constancy":"constanc","constant":"constant","knack":"knack","knackeries":"knackeri","knacks":"knack","knag":"knag","knave":"knave","knaves":"knave","knavish":"knavish","kneaded":"knead","kneading":"knead","knee":"knee","kneel":"kneel","kneeled":"kneel","kneeling":"kneel","kneels":"kneel","knees":"knee","knell":"knell","knelt":"knelt","knew":"knew","knick":"knick","knif":"knif","knife":"knife","knight":"knight","knights":"knight","knit":"knit","knits":"knit","knitted":"knit","knitting":"knit","knives":"knive","knob":"knob","knobs":"knob","knock":"knock","knocked":"knock","knocker":"knocker","knockers":"knocker","knocking":"knock","knocks":"knock","knopp":"knopp","knot":"knot","knots":"knot","lay":"lay","try":"tri"}

58
mcp-server/node_modules/lunr/test/index.html generated vendored Normal file
View File

@@ -0,0 +1,58 @@
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="/test/env/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script src="/test/env/mocha.js"></script>
<script src="/test/env/chai.js"></script>
<script src="/lunr.js"></script>
<script>
mocha.setup('tdd')
window.assert = chai.assert
window.withFixture = function (name, fn) {
var fixturePath = '/test/fixtures/' + name,
xhr = new XMLHttpRequest
xhr.addEventListener('load', function () {
if (this.status != 200) {
fn('non 200 response')
} else {
fn(null, this.responseText)
}
})
xhr.open('GET', fixturePath)
xhr.send()
}
</script>
<script src="/test/builder_test.js"></script>
<script src="/test/field_ref_test.js"></script>
<script src="/test/match_data_test.js"></script>
<script src="/test/pipeline_test.js"></script>
<script src="/test/query_lexer_test.js"></script>
<script src="/test/query_parser_test.js"></script>
<script src="/test/query_test.js"></script>
<script src="/test/search_test.js"></script>
<script src="/test/serialization_test.js"></script>
<script src="/test/set_test.js"></script>
<script src="/test/stemmer_test.js"></script>
<script src="/test/stop_word_filter_test.js"></script>
<script src="/test/token_set_test.js"></script>
<script src="/test/token_test.js"></script>
<script src="/test/tokenizer_test.js"></script>
<script src="/test/trimmer_test.js"></script>
<script src="/test/utils_test.js"></script>
<script src="/test/vector_test.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['lunr']);
mocha.run();
</script>
</body>
</html>

41
mcp-server/node_modules/lunr/test/match_data_test.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
suite('lunr.MatchData', function () {
suite('#combine', function () {
setup(function () {
this.match = new lunr.MatchData('foo', 'title', {
position: [1]
})
this.match.combine(new lunr.MatchData('bar', 'title', {
position: [2]
}))
this.match.combine(new lunr.MatchData('baz', 'body', {
position: [3]
}))
this.match.combine(new lunr.MatchData('baz', 'body', {
position: [4]
}))
})
test('#terms', function () {
assert.sameMembers(['foo', 'bar', 'baz'], Object.keys(this.match.metadata))
})
test('#metadata', function () {
assert.deepEqual(this.match.metadata.foo.title.position, [1])
assert.deepEqual(this.match.metadata.bar.title.position, [2])
assert.deepEqual(this.match.metadata.baz.body.position, [3, 4])
})
test('does not mutate source data', function () {
var metadata = { foo: [1] },
matchData1 = new lunr.MatchData('foo', 'title', metadata),
matchData2 = new lunr.MatchData('foo', 'title', metadata)
matchData1.combine(matchData2)
assert.deepEqual(metadata.foo, [1])
})
})
})

280
mcp-server/node_modules/lunr/test/pipeline_test.js generated vendored Normal file
View File

@@ -0,0 +1,280 @@
suite('lunr.Pipeline', function () {
var noop = function () {}
setup(function () {
this.existingRegisteredFunctions = lunr.Pipeline.registeredFunctions
this.existingWarnIfFunctionNotRegistered = lunr.Pipeline.warnIfFunctionNotRegistered
lunr.Pipeline.registeredFunctions = {}
lunr.Pipeline.warnIfFunctionNotRegistered = noop
this.pipeline = new lunr.Pipeline
})
teardown(function () {
lunr.Pipeline.registeredFunctions = this.existingRegisteredFunctions
lunr.Pipeline.warnIfFunctionNotRegistered = this.existingWarnIfFunctionNotRegistered
})
suite('#add', function () {
test('add function to pipeline', function () {
this.pipeline.add(noop)
assert.equal(1, this.pipeline._stack.length)
})
test('add multiple functions to the pipeline', function () {
this.pipeline.add(noop, noop)
assert.equal(2, this.pipeline._stack.length)
})
})
suite('#remove', function () {
test('function exists in pipeline', function () {
this.pipeline.add(noop)
assert.equal(1, this.pipeline._stack.length)
this.pipeline.remove(noop)
assert.equal(0, this.pipeline._stack.length)
})
test('function does not exist in pipeline', function () {
var fn = function () {}
this.pipeline.add(noop)
assert.equal(1, this.pipeline._stack.length)
this.pipeline.remove(fn)
assert.equal(1, this.pipeline._stack.length)
})
})
suite('#before', function () {
var fn = function () {}
test('other function exists', function () {
this.pipeline.add(noop)
this.pipeline.before(noop, fn)
assert.deepEqual([fn, noop], this.pipeline._stack)
})
test('other function does not exist', function () {
var action = function () {
this.pipeline.before(noop, fn)
}
assert.throws(action.bind(this))
assert.equal(0, this.pipeline._stack.length)
})
})
suite('#after', function () {
var fn = function () {}
test('other function exists', function () {
this.pipeline.add(noop)
this.pipeline.after(noop, fn)
assert.deepEqual([noop, fn], this.pipeline._stack)
})
test('other function does not exist', function () {
var action = function () {
this.pipeline.after(noop, fn)
}
assert.throws(action.bind(this))
assert.equal(0, this.pipeline._stack.length)
})
})
suite('#run', function () {
test('calling each function for each token', function () {
var count1 = 0, count2 = 0,
fn1 = function (t) { count1++; return t },
fn2 = function (t) { count2++; return t }
this.pipeline.add(fn1, fn2)
this.pipeline.run([1,2,3])
assert.equal(3, count1)
assert.equal(3, count2)
})
test('passes token to pipeline function', function () {
this.pipeline.add(function (token) {
assert.equal('foo', token)
})
this.pipeline.run(['foo'])
})
test('passes index to pipeline function', function () {
this.pipeline.add(function (_, index) {
assert.equal(0, index)
})
this.pipeline.run(['foo'])
})
test('passes entire token array to pipeline function', function () {
this.pipeline.add(function (_, _, tokens) {
assert.deepEqual(['foo'], tokens)
})
this.pipeline.run(['foo'])
})
test('passes output of one function as input to the next', function () {
this.pipeline.add(function (t) {
return t.toUpperCase()
})
this.pipeline.add(function (t) {
assert.equal('FOO', t)
})
this.pipeline.run(['foo'])
})
test('returns the results of the last function', function () {
this.pipeline.add(function (t) {
return t.toUpperCase()
})
assert.deepEqual(['FOO'], this.pipeline.run(['foo']))
})
test('filters out null, undefined and empty string values', function () {
var tokens = [],
output
// only pass on tokens for even token indexes
// return null for 'foo'
// return undefined for 'bar'
// return '' for 'baz'
this.pipeline.add(function (t, i) {
if (i == 4) {
return null
} else if (i == 5) {
return ''
} if (i % 2) {
return t
} else {
return undefined
}
})
this.pipeline.add(function (t) {
tokens.push(t)
return t
})
output = this.pipeline.run(['a', 'b', 'c', 'd', 'foo', 'bar', 'baz'])
assert.sameMembers(['b', 'd'], tokens)
assert.sameMembers(['b', 'd'], output)
})
suite('expanding tokens', function () {
test('passed to output', function () {
this.pipeline.add(function (t) {
return [t, t.toUpperCase()]
})
assert.sameMembers(["foo", "FOO"], this.pipeline.run(['foo']))
})
test('not passed to same function', function () {
var received = []
this.pipeline.add(function (t) {
received.push(t)
return [t, t.toUpperCase()]
})
this.pipeline.run(['foo'])
assert.sameMembers(['foo'], received)
})
test('passed to the next pipeline function', function () {
var received = []
this.pipeline.add(function (t) {
return [t, t.toUpperCase()]
})
this.pipeline.add(function (t) {
received.push(t)
})
this.pipeline.run(['foo'])
assert.sameMembers(['foo', 'FOO'], received)
})
})
})
suite('#toJSON', function () {
test('returns an array of registered function labels', function () {
var fn = function () {}
lunr.Pipeline.registerFunction(fn, 'fn')
this.pipeline.add(fn)
assert.sameMembers(['fn'], this.pipeline.toJSON())
})
})
suite('.registerFunction', function () {
setup(function () {
this.fn = function () {}
})
test('adds a label property to the function', function () {
lunr.Pipeline.registerFunction(this.fn, 'fn')
assert.equal('fn', this.fn.label)
})
test('adds function to the list of registered functions', function () {
lunr.Pipeline.registerFunction(this.fn, 'fn')
assert.equal(this.fn, lunr.Pipeline.registeredFunctions['fn'])
})
})
suite('.load', function () {
test('with registered functions', function () {
var fn = function () {},
serializedPipeline = ['fn'],
pipeline
lunr.Pipeline.registerFunction(fn, 'fn')
pipeline = lunr.Pipeline.load(serializedPipeline)
assert.equal(1, pipeline._stack.length)
assert.equal(fn, pipeline._stack[0])
})
test('with unregisterd functions', function () {
var serializedPipeline = ['fn']
assert.throws(function () {
lunr.Pipeline.load(serializedPipeline)
})
})
})
suite('#reset', function () {
test('empties the stack', function () {
this.pipeline.add(function () {})
assert.equal(1, this.pipeline._stack.length)
this.pipeline.reset()
assert.equal(0, this.pipeline._stack.length)
})
})
})

573
mcp-server/node_modules/lunr/test/query_lexer_test.js generated vendored Normal file
View File

@@ -0,0 +1,573 @@
suite('lunr.QueryLexer', function () {
suite('#run', function () {
var lex = function (str) {
var lexer = new lunr.QueryLexer(str)
lexer.run()
return lexer
}
suite('single term', function () {
setup(function () {
this.lexer = lex('foo')
})
test('produces 1 lexeme', function () {
assert.lengthOf(this.lexer.lexemes, 1)
})
suite('lexeme', function () {
setup(function () {
this.lexeme = this.lexer.lexemes[0]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.lexeme.type)
})
test('#str', function () {
assert.equal('foo', this.lexeme.str)
})
test('#start', function () {
assert.equal(0, this.lexeme.start)
})
test('#end', function () {
assert.equal(3, this.lexeme.end)
})
})
})
// embedded hyphens should not be confused with
// presence operators
suite('single term with hyphen', function () {
setup(function () {
this.lexer = lex('foo-bar')
})
test('produces 2 lexeme', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexeme', function () {
setup(function () {
this.fooLexeme = this.lexer.lexemes[0]
this.barLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.fooLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.barLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.fooLexeme.str)
assert.equal('bar', this.barLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fooLexeme.start)
assert.equal(4, this.barLexeme.start)
})
test('#end', function () {
assert.equal(3, this.fooLexeme.end)
assert.equal(7, this.barLexeme.end)
})
})
})
suite('term escape char', function () {
setup(function () {
this.lexer = lex("foo\\:bar")
})
test('produces 1 lexeme', function () {
assert.lengthOf(this.lexer.lexemes, 1)
})
suite('lexeme', function () {
setup(function () {
this.lexeme = this.lexer.lexemes[0]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.lexeme.type)
})
test('#str', function () {
assert.equal('foo:bar', this.lexeme.str)
})
test('#start', function () {
assert.equal(0, this.lexeme.start)
})
test('#end', function () {
assert.equal(8, this.lexeme.end)
})
})
})
suite('multiple terms', function () {
setup(function () {
this.lexer = lex('foo bar')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.fooLexeme = this.lexer.lexemes[0]
this.barLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.fooLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.barLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.fooLexeme.str)
assert.equal('bar', this.barLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fooLexeme.start)
assert.equal(4, this.barLexeme.start)
})
test('#end', function () {
assert.equal(3, this.fooLexeme.end)
assert.equal(7, this.barLexeme.end)
})
})
})
suite('multiple terms with presence', function () {
setup(function () {
this.lexer = lex('+foo +bar')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 4)
})
suite('lexemes', function () {
setup(function () {
this.fooPresenceLexeme = this.lexer.lexemes[0]
this.fooTermLexeme = this.lexer.lexemes[1]
this.barPresenceLexeme = this.lexer.lexemes[2]
this.barTermLexeme = this.lexer.lexemes[3]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.fooTermLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.barTermLexeme.type)
assert.equal(lunr.QueryLexer.PRESENCE, this.fooPresenceLexeme.type)
assert.equal(lunr.QueryLexer.PRESENCE, this.barPresenceLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.fooTermLexeme.str)
assert.equal('bar', this.barTermLexeme.str)
assert.equal('+', this.fooPresenceLexeme.str)
assert.equal('+', this.barPresenceLexeme.str)
})
})
})
suite('multiple terms with presence and fuzz', function () {
setup(function () {
this.lexer = lex('+foo~1 +bar')
})
test('produces n lexemes', function () {
assert.lengthOf(this.lexer.lexemes, 5)
})
suite('lexemes', function () {
setup(function () {
this.fooPresenceLexeme = this.lexer.lexemes[0]
this.fooTermLexeme = this.lexer.lexemes[1]
this.fooFuzzLexeme = this.lexer.lexemes[2]
this.barPresenceLexeme = this.lexer.lexemes[3]
this.barTermLexeme = this.lexer.lexemes[4]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.PRESENCE, this.fooPresenceLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.fooTermLexeme.type)
assert.equal(lunr.QueryLexer.EDIT_DISTANCE, this.fooFuzzLexeme.type)
assert.equal(lunr.QueryLexer.PRESENCE, this.barPresenceLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.barTermLexeme.type)
})
})
})
suite('separator length > 1', function () {
setup(function () {
this.lexer = lex('foo bar')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.fooLexeme = this.lexer.lexemes[0]
this.barLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.fooLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.barLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.fooLexeme.str)
assert.equal('bar', this.barLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fooLexeme.start)
assert.equal(7, this.barLexeme.start)
})
test('#end', function () {
assert.equal(3, this.fooLexeme.end)
assert.equal(10, this.barLexeme.end)
})
})
})
suite('hyphen (-) considered a seperator', function () {
setup(function () {
this.lexer = lex('foo-bar')
})
test('produces 1 lexeme', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
})
suite('term with field', function () {
setup(function () {
this.lexer = lex('title:foo')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.fieldLexeme = this.lexer.lexemes[0]
this.termLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.FIELD, this.fieldLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
})
test('#str', function () {
assert.equal('title', this.fieldLexeme.str)
assert.equal('foo', this.termLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fieldLexeme.start)
assert.equal(6, this.termLexeme.start)
})
test('#end', function () {
assert.equal(5, this.fieldLexeme.end)
assert.equal(9, this.termLexeme.end)
})
})
})
suite('term with field with escape char', function () {
setup(function () {
this.lexer = lex("ti\\:tle:foo")
})
test('produces 1 lexeme', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexeme', function () {
setup(function () {
this.fieldLexeme = this.lexer.lexemes[0]
this.termLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.FIELD, this.fieldLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
})
test('#str', function () {
assert.equal('ti:tle', this.fieldLexeme.str)
assert.equal('foo', this.termLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fieldLexeme.start)
assert.equal(8, this.termLexeme.start)
})
test('#end', function () {
assert.equal(7, this.fieldLexeme.end)
assert.equal(11, this.termLexeme.end)
})
})
})
suite('term with presence required', function () {
setup(function () {
this.lexer = lex('+foo')
})
test('produces 2 lexemes', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.presenceLexeme = this.lexer.lexemes[0]
this.termLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.PRESENCE, this.presenceLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
})
test('#str', function () {
assert.equal('+', this.presenceLexeme.str)
assert.equal('foo', this.termLexeme.str)
})
test('#start', function () {
assert.equal(1, this.termLexeme.start)
assert.equal(0, this.presenceLexeme.start)
})
test('#end', function () {
assert.equal(4, this.termLexeme.end)
assert.equal(1, this.presenceLexeme.end)
})
})
})
suite('term with field with presence required', function () {
setup(function () {
this.lexer = lex('+title:foo')
})
test('produces 3 lexemes', function () {
assert.lengthOf(this.lexer.lexemes, 3)
})
suite('lexemes', function () {
setup(function () {
this.presenceLexeme = this.lexer.lexemes[0]
this.fieldLexeme = this.lexer.lexemes[1]
this.termLexeme = this.lexer.lexemes[2]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.PRESENCE, this.presenceLexeme.type)
assert.equal(lunr.QueryLexer.FIELD, this.fieldLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
})
test('#str', function () {
assert.equal('+', this.presenceLexeme.str)
assert.equal('title', this.fieldLexeme.str)
assert.equal('foo', this.termLexeme.str)
})
test('#start', function () {
assert.equal(0, this.presenceLexeme.start)
assert.equal(1, this.fieldLexeme.start)
assert.equal(7, this.termLexeme.start)
})
test('#end', function () {
assert.equal(1, this.presenceLexeme.end)
assert.equal(6, this.fieldLexeme.end)
assert.equal(10, this.termLexeme.end)
})
})
})
suite('term with presence prohibited', function () {
setup(function () {
this.lexer = lex('-foo')
})
test('produces 2 lexemes', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.presenceLexeme = this.lexer.lexemes[0]
this.termLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.PRESENCE, this.presenceLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
})
test('#str', function () {
assert.equal('-', this.presenceLexeme.str)
assert.equal('foo', this.termLexeme.str)
})
test('#start', function () {
assert.equal(1, this.termLexeme.start)
assert.equal(0, this.presenceLexeme.start)
})
test('#end', function () {
assert.equal(4, this.termLexeme.end)
assert.equal(1, this.presenceLexeme.end)
})
})
})
suite('term with edit distance', function () {
setup(function () {
this.lexer = lex('foo~2')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.termLexeme = this.lexer.lexemes[0]
this.editDistanceLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
assert.equal(lunr.QueryLexer.EDIT_DISTANCE, this.editDistanceLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.termLexeme.str)
assert.equal('2', this.editDistanceLexeme.str)
})
test('#start', function () {
assert.equal(0, this.termLexeme.start)
assert.equal(4, this.editDistanceLexeme.start)
})
test('#end', function () {
assert.equal(3, this.termLexeme.end)
assert.equal(5, this.editDistanceLexeme.end)
})
})
})
suite('term with boost', function () {
setup(function () {
this.lexer = lex('foo^10')
})
test('produces 2 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 2)
})
suite('lexemes', function () {
setup(function () {
this.termLexeme = this.lexer.lexemes[0]
this.boostLexeme = this.lexer.lexemes[1]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
assert.equal(lunr.QueryLexer.BOOST, this.boostLexeme.type)
})
test('#str', function () {
assert.equal('foo', this.termLexeme.str)
assert.equal('10', this.boostLexeme.str)
})
test('#start', function () {
assert.equal(0, this.termLexeme.start)
assert.equal(4, this.boostLexeme.start)
})
test('#end', function () {
assert.equal(3, this.termLexeme.end)
assert.equal(6, this.boostLexeme.end)
})
})
})
suite('term with field, boost and edit distance', function () {
setup(function () {
this.lexer = lex('title:foo^10~5')
})
test('produces 4 lexems', function () {
assert.lengthOf(this.lexer.lexemes, 4)
})
suite('lexemes', function () {
setup(function () {
this.fieldLexeme = this.lexer.lexemes[0]
this.termLexeme = this.lexer.lexemes[1]
this.boostLexeme = this.lexer.lexemes[2]
this.editDistanceLexeme = this.lexer.lexemes[3]
})
test('#type', function () {
assert.equal(lunr.QueryLexer.FIELD, this.fieldLexeme.type)
assert.equal(lunr.QueryLexer.TERM, this.termLexeme.type)
assert.equal(lunr.QueryLexer.BOOST, this.boostLexeme.type)
assert.equal(lunr.QueryLexer.EDIT_DISTANCE, this.editDistanceLexeme.type)
})
test('#str', function () {
assert.equal('title', this.fieldLexeme.str)
assert.equal('foo', this.termLexeme.str)
assert.equal('10', this.boostLexeme.str)
assert.equal('5', this.editDistanceLexeme.str)
})
test('#start', function () {
assert.equal(0, this.fieldLexeme.start)
assert.equal(6, this.termLexeme.start)
assert.equal(10, this.boostLexeme.start)
assert.equal(13, this.editDistanceLexeme.start)
})
test('#end', function () {
assert.equal(5, this.fieldLexeme.end)
assert.equal(9, this.termLexeme.end)
assert.equal(12, this.boostLexeme.end)
assert.equal(14, this.editDistanceLexeme.end)
})
})
})
})
})

552
mcp-server/node_modules/lunr/test/query_parser_test.js generated vendored Normal file
View File

@@ -0,0 +1,552 @@
suite('lunr.QueryParser', function () {
var parse = function (q) {
var query = new lunr.Query (['title', 'body']),
parser = new lunr.QueryParser(q, query)
parser.parse()
return query.clauses
}
suite('#parse', function () {
suite('single term', function () {
setup(function () {
this.clauses = parse('foo')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
suite('clauses', function () {
setup(function () {
this.clause = this.clauses[0]
})
test('term', function () {
assert.equal('foo', this.clause.term)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clause.fields)
})
test('presence', function () {
assert.equal(lunr.Query.presence.OPTIONAL, this.clause.presence)
})
test('usePipeline', function () {
assert.ok(this.clause.usePipeline)
})
})
})
suite('single term, uppercase', function () {
setup(function () {
this.clauses = parse('FOO')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
suite('clauses', function () {
setup(function () {
this.clause = this.clauses[0]
})
test('term', function () {
assert.equal('foo', this.clause.term)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clause.fields)
})
test('usePipeline', function () {
assert.ok(this.clause.usePipeline)
})
})
})
suite('single term with wildcard', function () {
setup(function () {
this.clauses = parse('fo*')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
suite('clauses', function () {
setup(function () {
this.clause = this.clauses[0]
})
test('#term', function () {
assert.equal('fo*', this.clause.term)
})
test('#usePipeline', function () {
assert.ok(!this.clause.usePipeline)
})
})
})
suite('multiple terms', function () {
setup(function () {
this.clauses = parse('foo bar')
})
test('has 2 clause', function () {
assert.lengthOf(this.clauses, 2)
})
suite('clauses', function () {
test('#term', function () {
assert.equal('foo', this.clauses[0].term)
assert.equal('bar', this.clauses[1].term)
})
})
})
suite('multiple terms with presence', function () {
setup(function () {
this.clauses = parse('+foo +bar')
})
test('has 2 clause', function () {
assert.lengthOf(this.clauses, 2)
})
})
suite('edit distance followed by presence', function () {
setup(function () {
this.clauses = parse('foo~10 +bar')
})
test('has 2 clause', function () {
assert.lengthOf(this.clauses, 2)
})
suite('clauses', function () {
setup(function () {
this.fooClause = this.clauses[0]
this.barClause = this.clauses[1]
})
test('#term', function () {
assert.equal('foo', this.fooClause.term)
assert.equal('bar', this.barClause.term)
})
test('#presence', function () {
assert.equal(lunr.Query.presence.OPTIONAL, this.fooClause.presence)
assert.equal(lunr.Query.presence.REQUIRED, this.barClause.presence)
})
test('#editDistance', function () {
assert.equal(10, this.fooClause.editDistance)
// It feels dirty asserting that something is undefined
// but there is no Optional so this is what we are reduced to
assert.isUndefined(this.barClause.editDistance)
})
})
})
suite('boost followed by presence', function () {
setup(function () {
this.clauses = parse('foo^10 +bar')
})
test('has 2 clause', function () {
assert.lengthOf(this.clauses, 2)
})
suite('clauses', function () {
setup(function () {
this.fooClause = this.clauses[0]
this.barClause = this.clauses[1]
})
test('#term', function () {
assert.equal('foo', this.fooClause.term)
assert.equal('bar', this.barClause.term)
})
test('#presence', function () {
assert.equal(lunr.Query.presence.OPTIONAL, this.fooClause.presence)
assert.equal(lunr.Query.presence.REQUIRED, this.barClause.presence)
})
test('#boost', function () {
assert.equal(10, this.fooClause.boost)
assert.equal(1, this.barClause.boost)
})
})
})
suite('field without a term', function () {
test('fails with lunr.QueryParseError', function () {
assert.throws(function () { parse('title:') }, lunr.QueryParseError)
})
})
suite('unknown field', function () {
test('fails with lunr.QueryParseError', function () {
assert.throws(function () { parse('unknown:foo') }, lunr.QueryParseError)
})
})
suite('term with field', function () {
setup(function () {
this.clauses = parse('title:foo')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('clause contains only scoped field', function () {
assert.sameMembers(this.clauses[0].fields, ['title'])
})
})
suite('uppercase field with uppercase term', function () {
setup(function () {
// Using a different query to the rest of the tests
// so that only this test has to worry about an upcase field name
var query = new lunr.Query (['TITLE']),
parser = new lunr.QueryParser("TITLE:FOO", query)
parser.parse()
this.clauses = query.clauses
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('clause contains downcased term', function () {
assert.equal(this.clauses[0].term, 'foo')
})
test('clause contains only scoped field', function () {
assert.sameMembers(this.clauses[0].fields, ['TITLE'])
})
})
suite('multiple terms scoped to different fields', function () {
setup(function () {
this.clauses = parse('title:foo body:bar')
})
test('has 2 clauses', function () {
assert.lengthOf(this.clauses, 2)
})
test('fields', function () {
assert.sameMembers(['title'], this.clauses[0].fields)
assert.sameMembers(['body'], this.clauses[1].fields)
})
test('terms', function () {
assert.equal('foo', this.clauses[0].term)
assert.equal('bar', this.clauses[1].term)
})
})
suite('single term with edit distance', function () {
setup(function () {
this.clauses = parse('foo~2')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('editDistance', function () {
assert.equal(2, this.clauses[0].editDistance)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
})
})
suite('multiple terms with edit distance', function () {
setup(function () {
this.clauses = parse('foo~2 bar~3')
})
test('has 2 clauses', function () {
assert.lengthOf(this.clauses, 2)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
assert.equal('bar', this.clauses[1].term)
})
test('editDistance', function () {
assert.equal(2, this.clauses[0].editDistance)
assert.equal(3, this.clauses[1].editDistance)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
assert.sameMembers(['title', 'body'], this.clauses[1].fields)
})
})
suite('single term scoped to field with edit distance', function () {
setup(function () {
this.clauses = parse('title:foo~2')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('editDistance', function () {
assert.equal(2, this.clauses[0].editDistance)
})
test('fields', function () {
assert.sameMembers(['title'], this.clauses[0].fields)
})
})
suite('non-numeric edit distance', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () { parse('foo~a') }, lunr.QueryParseError)
})
})
suite('edit distance without a term', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () { parse('~2') }, lunr.QueryParseError)
})
})
suite('single term with boost', function () {
setup(function () {
this.clauses = parse('foo^2')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(2, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
})
})
suite('non-numeric boost', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () { parse('foo^a') }, lunr.QueryParseError)
})
})
suite('boost without a term', function () {
test('throws lunr.QueryParseError', function () {
assert.throws(function () { parse('^2') }, lunr.QueryParseError)
})
})
suite('multiple terms with boost', function () {
setup(function () {
this.clauses = parse('foo^2 bar^3')
})
test('has 2 clauses', function () {
assert.lengthOf(this.clauses, 2)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
assert.equal('bar', this.clauses[1].term)
})
test('boost', function () {
assert.equal(2, this.clauses[0].boost)
assert.equal(3, this.clauses[1].boost)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
assert.sameMembers(['title', 'body'], this.clauses[1].fields)
})
})
suite('term scoped by field with boost', function () {
setup(function () {
this.clauses = parse('title:foo^2')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(2, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title'], this.clauses[0].fields)
})
})
suite('term with presence required', function () {
setup(function () {
this.clauses = parse('+foo')
})
test('has 1 clauses', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(1, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
})
test('presence', function () {
assert.equal(lunr.Query.presence.REQUIRED, this.clauses[0].presence)
})
})
suite('term with presence prohibited', function () {
setup(function () {
this.clauses = parse('-foo')
})
test('has 1 clauses', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(1, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
})
test('presence', function () {
assert.equal(lunr.Query.presence.PROHIBITED, this.clauses[0].presence)
})
})
suite('term scoped by field with presence required', function () {
setup(function () {
this.clauses = parse('+title:foo')
})
test('has 1 clauses', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(1, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title'], this.clauses[0].fields)
})
test('presence', function () {
assert.equal(lunr.Query.presence.REQUIRED, this.clauses[0].presence)
})
})
suite('term scoped by field with presence prohibited', function () {
setup(function () {
this.clauses = parse('-title:foo')
})
test('has 1 clauses', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('boost', function () {
assert.equal(1, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title'], this.clauses[0].fields)
})
test('presence', function () {
assert.equal(lunr.Query.presence.PROHIBITED, this.clauses[0].presence)
})
})
})
suite('term with boost and edit distance', function () {
setup(function () {
this.clauses = parse('foo^2~3')
})
test('has 1 clause', function () {
assert.lengthOf(this.clauses, 1)
})
test('term', function () {
assert.equal('foo', this.clauses[0].term)
})
test('editDistance', function () {
assert.equal(3, this.clauses[0].editDistance)
})
test('boost', function () {
assert.equal(2, this.clauses[0].boost)
})
test('fields', function () {
assert.sameMembers(['title', 'body'], this.clauses[0].fields)
})
})
})

244
mcp-server/node_modules/lunr/test/query_test.js generated vendored Normal file
View File

@@ -0,0 +1,244 @@
suite('lunr.Query', function () {
var allFields = ['title', 'body']
suite('#term', function () {
setup(function () {
this.query = new lunr.Query (allFields)
})
suite('single string term', function () {
setup(function () {
this.query.term('foo')
})
test('adds a single clause', function () {
assert.equal(this.query.clauses.length, 1)
})
test('clause has the correct term', function () {
assert.equal(this.query.clauses[0].term, 'foo')
})
})
suite('single token term', function () {
setup(function () {
this.query.term(new lunr.Token('foo'))
})
test('adds a single clause', function () {
assert.equal(this.query.clauses.length, 1)
})
test('clause has the correct term', function () {
assert.equal(this.query.clauses[0].term, 'foo')
})
})
suite('multiple string terms', function () {
setup(function () {
this.query.term(['foo', 'bar'])
})
test('adds a single clause', function () {
assert.equal(this.query.clauses.length, 2)
})
test('clause has the correct term', function () {
var terms = this.query.clauses.map(function (c) { return c.term })
assert.sameMembers(terms, ['foo', 'bar'])
})
})
suite('multiple string terms with options', function () {
setup(function () {
this.query.term(['foo', 'bar'], { usePipeline: false })
})
test('clause has the correct term', function () {
var terms = this.query.clauses.map(function (c) { return c.term })
assert.sameMembers(terms, ['foo', 'bar'])
})
})
suite('multiple token terms', function () {
setup(function () {
this.query.term(lunr.tokenizer('foo bar'))
})
test('adds a single clause', function () {
assert.equal(this.query.clauses.length, 2)
})
test('clause has the correct term', function () {
var terms = this.query.clauses.map(function (c) { return c.term })
assert.sameMembers(terms, ['foo', 'bar'])
})
})
})
suite('#clause', function () {
setup(function () {
this.query = new lunr.Query (allFields)
})
suite('defaults', function () {
setup(function () {
this.query.clause({term: 'foo'})
this.clause = this.query.clauses[0]
})
test('fields', function () {
assert.sameMembers(this.clause.fields, allFields)
})
test('boost', function () {
assert.equal(this.clause.boost, 1)
})
test('usePipeline', function () {
assert.isTrue(this.clause.usePipeline)
})
})
suite('specified', function () {
setup(function () {
this.query.clause({
term: 'foo',
boost: 10,
fields: ['title'],
usePipeline: false
})
this.clause = this.query.clauses[0]
})
test('fields', function () {
assert.sameMembers(this.clause.fields, ['title'])
})
test('boost', function () {
assert.equal(this.clause.boost, 10)
})
test('usePipeline', function () {
assert.isFalse(this.clause.usePipeline)
})
})
suite('wildcards', function () {
suite('none', function () {
setup(function () {
this.query.clause({
term: 'foo',
wildcard: lunr.Query.wildcard.NONE
})
this.clause = this.query.clauses[0]
})
test('no wildcard', function () {
assert.equal(this.clause.term, 'foo')
})
})
suite('leading', function () {
setup(function () {
this.query.clause({
term: 'foo',
wildcard: lunr.Query.wildcard.LEADING
})
this.clause = this.query.clauses[0]
})
test('adds wildcard', function () {
assert.equal(this.clause.term, '*foo')
})
})
suite('trailing', function () {
setup(function () {
this.query.clause({
term: 'foo',
wildcard: lunr.Query.wildcard.TRAILING
})
this.clause = this.query.clauses[0]
})
test('adds wildcard', function () {
assert.equal(this.clause.term, 'foo*')
})
})
suite('leading and trailing', function () {
setup(function () {
this.query.clause({
term: 'foo',
wildcard: lunr.Query.wildcard.TRAILING | lunr.Query.wildcard.LEADING
})
this.clause = this.query.clauses[0]
})
test('adds wildcards', function () {
assert.equal(this.clause.term, '*foo*')
})
})
suite('existing', function () {
setup(function () {
this.query.clause({
term: '*foo*',
wildcard: lunr.Query.wildcard.TRAILING | lunr.Query.wildcard.LEADING
})
this.clause = this.query.clauses[0]
})
test('no additional wildcards', function () {
assert.equal(this.clause.term, '*foo*')
})
})
})
})
suite('#isNegated', function () {
setup(function () {
this.query = new lunr.Query (allFields)
})
suite('all prohibited', function () {
setup(function () {
this.query.term('foo', { presence: lunr.Query.presence.PROHIBITED })
this.query.term('bar', { presence: lunr.Query.presence.PROHIBITED })
})
test('is negated', function () {
assert.isTrue(this.query.isNegated())
})
})
suite('some prohibited', function () {
setup(function () {
this.query.term('foo', { presence: lunr.Query.presence.PROHIBITED })
this.query.term('bar', { presence: lunr.Query.presence.REQUIRED })
})
test('is negated', function () {
assert.isFalse(this.query.isNegated())
})
})
suite('none prohibited', function () {
setup(function () {
this.query.term('foo', { presence: lunr.Query.presence.OPTIONAL })
this.query.term('bar', { presence: lunr.Query.presence.REQUIRED })
})
test('is negated', function () {
assert.isFalse(this.query.isNegated())
})
})
})
})

1100
mcp-server/node_modules/lunr/test/search_test.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
suite('serialization', function () {
setup(function () {
var documents = [{
id: 'a',
title: 'Mr. Green kills Colonel Mustard',
body: 'Mr. Green killed Colonel Mustard in the study with the candlestick. Mr. Green is not a very nice fellow.',
wordCount: 19
},{
id: 'b',
title: 'Plumb waters plant',
body: 'Professor Plumb has a green plant in his study',
wordCount: 9
},{
id: 'c',
title: 'Scarlett helps Professor',
body: 'Miss Scarlett watered Professor Plumbs green plant while he was away from his office last week.',
wordCount: 16
},{
id: 'd',
title: 'All about JavaScript',
body: 'JavaScript objects have a special __proto__ property',
wordCount: 7
}]
this.idx = lunr(function () {
this.ref('id')
this.field('title')
this.field('body')
documents.forEach(function (document) {
this.add(document)
}, this)
})
this.serializedIdx = JSON.stringify(this.idx)
this.loadedIdx = lunr.Index.load(JSON.parse(this.serializedIdx))
})
test('search', function () {
var idxResults = this.idx.search('green'),
serializedResults = this.loadedIdx.search('green')
assert.deepEqual(idxResults, serializedResults)
})
test('__proto__ double serialization', function () {
var doubleLoadedIdx = lunr.Index.load(JSON.parse(JSON.stringify(this.loadedIdx))),
idxResults = this.idx.search('__proto__'),
doubleSerializedResults = doubleLoadedIdx.search('__proto__')
assert.deepEqual(idxResults, doubleSerializedResults)
})
})

147
mcp-server/node_modules/lunr/test/set_test.js generated vendored Normal file
View File

@@ -0,0 +1,147 @@
suite('lunr.Set', function () {
suite('#contains', function () {
suite('complete set', function () {
test('returns true', function () {
assert.isOk(lunr.Set.complete.contains('foo'))
})
})
suite('empty set', function () {
test('returns false', function () {
assert.isNotOk(lunr.Set.empty.contains('foo'))
})
})
suite('populated set', function () {
setup(function () {
this.set = new lunr.Set (['foo'])
})
test('element contained in set', function () {
assert.isOk(this.set.contains('foo'))
})
test('element not contained in set', function () {
assert.isNotOk(this.set.contains('bar'))
})
})
})
suite('#union', function () {
setup(function () {
this.set = new lunr.Set(['foo'])
})
suite('complete set', function () {
test('union is complete', function () {
var result = lunr.Set.complete.union(this.set)
assert.isOk(result.contains('foo'))
assert.isOk(result.contains('bar'))
})
})
suite('empty set', function () {
test('contains element', function () {
var result = lunr.Set.empty.union(this.set)
assert.isOk(result.contains('foo'))
assert.isNotOk(result.contains('bar'))
})
})
suite('populated set', function () {
suite('with other populated set', function () {
test('contains both elements', function () {
var target = new lunr.Set (['bar'])
var result = target.union(this.set)
assert.isOk(result.contains('foo'))
assert.isOk(result.contains('bar'))
assert.isNotOk(result.contains('baz'))
})
})
suite('with empty set', function () {
test('contains all elements', function () {
var target = new lunr.Set (['bar'])
var result = target.union(lunr.Set.empty)
assert.isOk(result.contains('bar'))
assert.isNotOk(result.contains('baz'))
})
})
suite('with complete set', function () {
test('contains all elements', function () {
var target = new lunr.Set (['bar'])
var result = target.union(lunr.Set.complete)
assert.isOk(result.contains('foo'))
assert.isOk(result.contains('bar'))
assert.isOk(result.contains('baz'))
})
})
})
})
suite('#intersect', function () {
setup(function () {
this.set = new lunr.Set(['foo'])
})
suite('complete set', function () {
test('contains element', function () {
var result = lunr.Set.complete.intersect(this.set)
assert.isOk(result.contains('foo'))
assert.isNotOk(result.contains('bar'))
})
})
suite('empty set', function () {
test('does not contain element', function () {
var result = lunr.Set.empty.intersect(this.set)
assert.isNotOk(result.contains('foo'))
})
})
suite('populated set', function () {
suite('no intersection', function () {
test('does not contain intersection elements', function () {
var target = new lunr.Set (['bar'])
var result = target.intersect(this.set)
assert.isNotOk(result.contains('foo'))
assert.isNotOk(result.contains('bar'))
})
})
suite('intersection', function () {
test('contains intersection elements', function () {
var target = new lunr.Set (['foo', 'bar'])
var result = target.intersect(this.set)
assert.isOk(result.contains('foo'))
assert.isNotOk(result.contains('bar'))
})
})
suite('with empty set', function () {
test('returns empty set', function () {
var target = new lunr.Set(['foo']),
result = target.intersect(lunr.Set.empty)
assert.isNotOk(result.contains('foo'))
})
})
suite('with complete set', function () {
test('returns populated set', function () {
var target = new lunr.Set(['foo']),
result = target.intersect(lunr.Set.complete)
assert.isOk(result.contains('foo'))
assert.isNotOk(result.contains('bar'))
})
})
})
})
})

26
mcp-server/node_modules/lunr/test/stemmer_test.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
suite('lunr.stemmer', function () {
test('reduces words to their stem', function (done) {
withFixture('stemming_vocab.json', function (err, fixture) {
if (err != null) {
throw err
}
var testData = JSON.parse(fixture)
Object.keys(testData).forEach(function (word) {
var expected = testData[word],
token = new lunr.Token(word),
result = lunr.stemmer(token).toString()
assert.equal(expected, result)
})
done()
})
})
test('is a registered pipeline function', function () {
assert.equal('stemmer', lunr.stemmer.label)
assert.equal(lunr.stemmer, lunr.Pipeline.registeredFunctions['stemmer'])
})
})

View File

@@ -0,0 +1,30 @@
suite('lunr.stopWordFilter', function () {
test('filters stop words', function () {
var stopWords = ['the', 'and', 'but', 'than', 'when']
stopWords.forEach(function (word) {
assert.isUndefined(lunr.stopWordFilter(word))
})
})
test('ignores non stop words', function () {
var nonStopWords = ['interesting', 'words', 'pass', 'through']
nonStopWords.forEach(function (word) {
assert.equal(word, lunr.stopWordFilter(word))
})
})
test('ignores properties of Object.prototype', function () {
var nonStopWords = ['constructor', 'hasOwnProperty', 'toString', 'valueOf']
nonStopWords.forEach(function (word) {
assert.equal(word, lunr.stopWordFilter(word))
})
})
test('is a registered pipeline function', function () {
assert.equal('stopWordFilter', lunr.stopWordFilter.label)
assert.equal(lunr.stopWordFilter, lunr.Pipeline.registeredFunctions['stopWordFilter'])
})
})

13
mcp-server/node_modules/lunr/test/test_helper.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
var lunr = require('../lunr.js'),
assert = require('chai').assert,
fs = require('fs'),
path = require('path')
var withFixture = function (name, fn) {
var fixturePath = path.join('test', 'fixtures', name)
fs.readFile(fixturePath, fn)
}
global.lunr = lunr
global.assert = assert
global.withFixture = withFixture

327
mcp-server/node_modules/lunr/test/token_set_test.js generated vendored Normal file
View File

@@ -0,0 +1,327 @@
suite('lunr.TokenSet', function () {
suite('#toString', function () {
test('includes node finality', function () {
var nonFinal = new lunr.TokenSet,
final = new lunr.TokenSet,
otherFinal = new lunr.TokenSet
final.final = true
otherFinal.final = true
assert.notEqual(nonFinal.toString(), final.toString())
assert.equal(otherFinal.toString(), final.toString())
})
test('includes all edges', function () {
var zeroEdges = new lunr.TokenSet,
oneEdge = new lunr.TokenSet,
twoEdges = new lunr.TokenSet
oneEdge.edges['a'] = 1
twoEdges.edges['a'] = 1
twoEdges.edges['b'] = 1
assert.notEqual(zeroEdges.toString(), oneEdge.toString())
assert.notEqual(twoEdges.toString(), oneEdge.toString())
assert.notEqual(twoEdges.toString(), zeroEdges.toString())
})
test('includes edge id', function () {
var childA = new lunr.TokenSet,
childB = new lunr.TokenSet,
parentA = new lunr.TokenSet,
parentB = new lunr.TokenSet,
parentC = new lunr.TokenSet
parentA.edges['a'] = childA
parentB.edges['a'] = childB
parentC.edges['a'] = childB
assert.equal(parentB.toString(), parentC.toString())
assert.notEqual(parentA.toString(), parentC.toString())
assert.notEqual(parentA.toString(), parentB.toString())
})
})
suite('.fromString', function () {
test('without wildcard', function () {
lunr.TokenSet._nextId = 1
var x = lunr.TokenSet.fromString('a')
assert.equal(x.toString(), '0a2')
assert.isOk(x.edges['a'].final)
})
test('with trailing wildcard', function () {
var x = lunr.TokenSet.fromString('a*'),
wild = x.edges['a'].edges['*']
// a state reached by a wildcard has
// an edge with a wildcard to itself.
// the resulting automota is
// non-determenistic
assert.equal(wild, wild.edges['*'])
assert.isOk(wild.final)
})
})
suite('.fromArray', function () {
test('with unsorted array', function () {
assert.throws(function () {
lunr.TokenSet.fromArray(['z', 'a'])
})
})
test('with sorted array', function () {
var tokenSet = lunr.TokenSet.fromArray(['a', 'z'])
assert.deepEqual(['a', 'z'], tokenSet.toArray().sort())
})
test('is minimal', function () {
var tokenSet = lunr.TokenSet.fromArray(['ac', 'dc']),
acNode = tokenSet.edges['a'].edges['c'],
dcNode = tokenSet.edges['d'].edges['c']
assert.deepEqual(acNode, dcNode)
})
})
suite('#toArray', function () {
test('includes all words', function () {
var words = ['bat', 'cat'],
tokenSet = lunr.TokenSet.fromArray(words)
assert.sameMembers(words, tokenSet.toArray())
})
test('includes single words', function () {
var word = 'bat',
tokenSet = lunr.TokenSet.fromString(word)
assert.sameMembers([word], tokenSet.toArray())
})
})
suite('#intersect', function () {
test('no intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('bar'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('simple intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('cat'),
z = x.intersect(y)
assert.sameMembers(['cat'], z.toArray())
})
test('trailing wildcard intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('c*'),
z = x.intersect(y)
assert.sameMembers(['cat'], z.toArray())
})
test('trailing wildcard no intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('b*'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('leading wildcard intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('*t'),
z = x.intersect(y)
assert.sameMembers(['cat'], z.toArray())
})
test('leading wildcard backtracking intersection', function () {
var x = lunr.TokenSet.fromString('aaacbab'),
y = lunr.TokenSet.fromString('*ab'),
z = x.intersect(y)
assert.sameMembers(['aaacbab'], z.toArray())
})
test('leading wildcard no intersection', function () {
var x = lunr.TokenSet.fromString('cat'),
y = lunr.TokenSet.fromString('*r'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('leading wildcard backtracking no intersection', function () {
var x = lunr.TokenSet.fromString('aaabdcbc'),
y = lunr.TokenSet.fromString('*abc'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('contained wildcard intersection', function () {
var x = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromString('f*o'),
z = x.intersect(y)
assert.sameMembers(['foo'], z.toArray())
})
test('contained wildcard backtracking intersection', function () {
var x = lunr.TokenSet.fromString('ababc'),
y = lunr.TokenSet.fromString('a*bc'),
z = x.intersect(y)
assert.sameMembers(['ababc'], z.toArray())
})
test('contained wildcard no intersection', function () {
var x = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromString('b*r'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('contained wildcard backtracking no intersection', function () {
var x = lunr.TokenSet.fromString('ababc'),
y = lunr.TokenSet.fromString('a*ac'),
z = x.intersect(y)
assert.equal(0, z.toArray().length)
})
test('wildcard matches zero or more characters', function () {
var x = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromString('foo*'),
z = x.intersect(y)
assert.sameMembers(['foo'], z.toArray())
})
// This test is intended to prevent 'bugs' that have lead to these
// kind of intersections taking a _very_ long time. The assertion
// is not of interest, just that the test does not timeout.
test('catastrophic backtracking with leading characters', function () {
var x = lunr.TokenSet.fromString('fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
y = lunr.TokenSet.fromString('*ff'),
z = x.intersect(y)
assert.equal(1, z.toArray().length)
})
test('leading and trailing backtracking intersection', function () {
var x = lunr.TokenSet.fromString('acbaabab'),
y = lunr.TokenSet.fromString('*ab*'),
z = x.intersect(y)
assert.sameMembers(['acbaabab'], z.toArray())
})
test('multiple contained wildcard backtracking', function () {
var x = lunr.TokenSet.fromString('acbaabab'),
y = lunr.TokenSet.fromString('a*ba*b'),
z = x.intersect(y)
assert.sameMembers(['acbaabab'], z.toArray())
})
test('intersect with fuzzy string substitution', function () {
var x1 = lunr.TokenSet.fromString('bar'),
x2 = lunr.TokenSet.fromString('cur'),
x3 = lunr.TokenSet.fromString('cat'),
x4 = lunr.TokenSet.fromString('car'),
x5 = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromFuzzyString('car', 1)
assert.sameMembers(x1.intersect(y).toArray(), ["bar"])
assert.sameMembers(x2.intersect(y).toArray(), ["cur"])
assert.sameMembers(x3.intersect(y).toArray(), ["cat"])
assert.sameMembers(x4.intersect(y).toArray(), ["car"])
assert.equal(x5.intersect(y).toArray().length, 0)
})
test('intersect with fuzzy string deletion', function () {
var x1 = lunr.TokenSet.fromString('ar'),
x2 = lunr.TokenSet.fromString('br'),
x3 = lunr.TokenSet.fromString('ba'),
x4 = lunr.TokenSet.fromString('bar'),
x5 = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromFuzzyString('bar', 1)
assert.sameMembers(x1.intersect(y).toArray(), ["ar"])
assert.sameMembers(x2.intersect(y).toArray(), ["br"])
assert.sameMembers(x3.intersect(y).toArray(), ["ba"])
assert.sameMembers(x4.intersect(y).toArray(), ["bar"])
assert.equal(x5.intersect(y).toArray().length, 0)
})
test('intersect with fuzzy string insertion', function () {
var x1 = lunr.TokenSet.fromString('bbar'),
x2 = lunr.TokenSet.fromString('baar'),
x3 = lunr.TokenSet.fromString('barr'),
x4 = lunr.TokenSet.fromString('bar'),
x5 = lunr.TokenSet.fromString('ba'),
x6 = lunr.TokenSet.fromString('foo'),
x7 = lunr.TokenSet.fromString('bara'),
y = lunr.TokenSet.fromFuzzyString('bar', 1)
assert.sameMembers(x1.intersect(y).toArray(), ["bbar"])
assert.sameMembers(x2.intersect(y).toArray(), ["baar"])
assert.sameMembers(x3.intersect(y).toArray(), ["barr"])
assert.sameMembers(x4.intersect(y).toArray(), ["bar"])
assert.sameMembers(x5.intersect(y).toArray(), ["ba"])
assert.equal(x6.intersect(y).toArray().length, 0)
assert.sameMembers(x7.intersect(y).toArray(), ["bara"])
})
test('intersect with fuzzy string transpose', function () {
var x1 = lunr.TokenSet.fromString('abr'),
x2 = lunr.TokenSet.fromString('bra'),
x3 = lunr.TokenSet.fromString('foo'),
y = lunr.TokenSet.fromFuzzyString('bar', 1)
assert.sameMembers(x1.intersect(y).toArray(), ["abr"])
assert.sameMembers(x2.intersect(y).toArray(), ["bra"])
assert.equal(x3.intersect(y).toArray().length, 0)
})
test('fuzzy string insertion', function () {
var x = lunr.TokenSet.fromString('abcxx'),
y = lunr.TokenSet.fromFuzzyString('abc', 2)
assert.sameMembers(x.intersect(y).toArray(), ['abcxx'])
})
test('fuzzy string substitution', function () {
var x = lunr.TokenSet.fromString('axx'),
y = lunr.TokenSet.fromFuzzyString('abc', 2)
assert.sameMembers(x.intersect(y).toArray(), ['axx'])
})
test('fuzzy string deletion', function () {
var x = lunr.TokenSet.fromString('a'),
y = lunr.TokenSet.fromFuzzyString('abc', 2)
assert.sameMembers(x.intersect(y).toArray(), ['a'])
})
test('fuzzy string transpose', function () {
var x = lunr.TokenSet.fromString('bca'),
y = lunr.TokenSet.fromFuzzyString('abc', 2)
assert.sameMembers(x.intersect(y).toArray(), ['bca'])
})
})
})

60
mcp-server/node_modules/lunr/test/token_test.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
suite('lunr.Token', function () {
suite('#toString', function () {
test('converts the token to a string', function () {
var token = new lunr.Token('foo')
assert.equal('foo', token.toString())
})
})
suite('#metadata', function () {
test('can attach arbitrary metadata', function () {
var token = new lunr.Token('foo', { length: 3 })
assert.equal(3, token.metadata.length)
})
})
suite('#update', function () {
test('can update the token value', function () {
var token = new lunr.Token('foo')
token.update(function (s) {
return s.toUpperCase()
})
assert.equal('FOO', token.toString())
})
test('metadata is yielded when updating', function () {
var metadata = { bar: true },
token = new lunr.Token('foo', metadata),
yieldedMetadata
token.update(function (_, md) {
yieldedMetadata = md
})
assert.equal(metadata, yieldedMetadata)
})
})
suite('#clone', function () {
var token = new lunr.Token('foo', { bar: true })
test('clones value', function () {
assert.equal(token.toString(), token.clone().toString())
})
test('clones metadata', function () {
assert.equal(token.metadata, token.clone().metadata)
})
test('clone and modify', function () {
var clone = token.clone(function (s) {
return s.toUpperCase()
})
assert.equal('FOO', clone.toString())
assert.equal(token.metadata, clone.metadata)
})
})
})

114
mcp-server/node_modules/lunr/test/tokenizer_test.js generated vendored Normal file
View File

@@ -0,0 +1,114 @@
suite('lunr.tokenizer', function () {
var toString = function (o) { return o.toString() }
test('splitting into tokens', function () {
var tokens = lunr.tokenizer('foo bar baz')
.map(toString)
assert.sameMembers(['foo', 'bar', 'baz'], tokens)
})
test('downcases tokens', function () {
var tokens = lunr.tokenizer('Foo BAR BAZ')
.map(toString)
assert.sameMembers(['foo', 'bar', 'baz'], tokens)
})
test('array of strings', function () {
var tokens = lunr.tokenizer(['foo', 'bar', 'baz'])
.map(toString)
assert.sameMembers(['foo', 'bar', 'baz'], tokens)
})
test('undefined is converted to empty string', function () {
var tokens = lunr.tokenizer(['foo', undefined, 'baz'])
.map(toString)
assert.sameMembers(['foo', '', 'baz'], tokens)
})
test('null is converted to empty string', function () {
var tokens = lunr.tokenizer(['foo', null, 'baz'])
.map(toString)
assert.sameMembers(['foo', '', 'baz'], tokens)
})
test('multiple white space is stripped', function () {
var tokens = lunr.tokenizer(' foo bar baz ')
.map(toString)
assert.sameMembers(['foo', 'bar', 'baz'], tokens)
})
test('handling null-like arguments', function () {
assert.lengthOf(lunr.tokenizer(), 0)
assert.lengthOf(lunr.tokenizer(undefined), 0)
assert.lengthOf(lunr.tokenizer(null), 0)
})
test('converting a date to tokens', function () {
var date = new Date(Date.UTC(2013, 0, 1, 12))
// NOTE: slicing here to prevent asserting on parts
// of the date that might be affected by the timezone
// the test is running in.
assert.sameMembers(['tue', 'jan', '01', '2013'], lunr.tokenizer(date).slice(0, 4).map(toString))
})
test('converting a number to tokens', function () {
assert.equal('41', lunr.tokenizer(41).map(toString))
})
test('converting a boolean to tokens', function () {
assert.equal('false', lunr.tokenizer(false).map(toString))
})
test('converting an object to tokens', function () {
var obj = {
toString: function () { return 'custom object' }
}
assert.sameMembers(lunr.tokenizer(obj).map(toString), ['custom', 'object'])
})
test('splits strings with hyphens', function () {
assert.sameMembers(lunr.tokenizer('foo-bar').map(toString), ['foo', 'bar'])
})
test('splits strings with hyphens and spaces', function () {
assert.sameMembers(lunr.tokenizer('foo - bar').map(toString), ['foo', 'bar'])
})
test('tracking the token index', function () {
var tokens = lunr.tokenizer('foo bar')
assert.equal(tokens[0].metadata.index, 0)
assert.equal(tokens[1].metadata.index, 1)
})
test('tracking the token position', function () {
var tokens = lunr.tokenizer('foo bar')
assert.deepEqual(tokens[0].metadata.position, [0, 3])
assert.deepEqual(tokens[1].metadata.position, [4, 3])
})
test('tracking the token position with additional left-hand whitespace', function () {
var tokens = lunr.tokenizer(' foo bar')
assert.deepEqual(tokens[0].metadata.position, [1, 3])
assert.deepEqual(tokens[1].metadata.position, [5, 3])
})
test('tracking the token position with additional right-hand whitespace', function () {
var tokens = lunr.tokenizer('foo bar ')
assert.deepEqual(tokens[0].metadata.position, [0, 3])
assert.deepEqual(tokens[1].metadata.position, [4, 3])
})
test('providing additional metadata', function () {
var tokens = lunr.tokenizer('foo bar', { 'hurp': 'durp' })
assert.deepEqual(tokens[0].metadata.hurp, 'durp')
assert.deepEqual(tokens[1].metadata.hurp, 'durp')
})
})

29
mcp-server/node_modules/lunr/test/trimmer_test.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
suite('lunr.trimmer', function () {
test('latin characters', function () {
var token = new lunr.Token ('hello')
assert.equal(lunr.trimmer(token).toString(), token.toString())
})
suite('punctuation', function () {
var trimmerTest = function (description, str, expected) {
test(description, function () {
var token = new lunr.Token(str),
trimmed = lunr.trimmer(token).toString()
assert.equal(expected, trimmed)
})
}
trimmerTest('full stop', 'hello.', 'hello')
trimmerTest('inner apostrophe', "it's", "it's")
trimmerTest('trailing apostrophe', "james'", 'james')
trimmerTest('exclamation mark', 'stop!', 'stop')
trimmerTest('comma', 'first,', 'first')
trimmerTest('brackets', '[tag]', 'tag')
})
test('is a registered pipeline function', function () {
assert.equal(lunr.trimmer.label, 'trimmer')
assert.equal(lunr.Pipeline.registeredFunctions['trimmer'], lunr.trimmer)
})
})

77
mcp-server/node_modules/lunr/test/utils_test.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
suite('lunr.utils', function () {
suite('#clone', function () {
var subject = function (obj) {
setup(function () {
this.obj = obj
this.clone = lunr.utils.clone(obj)
})
}
suite('handles null', function () {
subject(null)
test('returns null', function () {
assert.equal(null, this.clone)
assert.equal(this.obj, this.clone)
})
})
suite('handles undefined', function () {
subject(undefined)
test('returns null', function () {
assert.equal(undefined, this.clone)
assert.equal(this.obj, this.clone)
})
})
suite('object with primatives', function () {
subject({
number: 1,
string: 'foo',
bool: true
})
test('clones number correctly', function () {
assert.equal(this.obj.number, this.clone.number)
})
test('clones string correctly', function () {
assert.equal(this.obj.string, this.clone.string)
})
test('clones bool correctly', function () {
assert.equal(this.obj.bool, this.clone.bool)
})
})
suite('object with array property', function () {
subject({
array: [1, 2, 3]
})
test('clones array correctly', function () {
assert.deepEqual(this.obj.array, this.clone.array)
})
test('mutations on clone do not affect orginial', function () {
this.clone.array.push(4)
assert.notDeepEqual(this.obj.array, this.clone.array)
assert.equal(this.obj.array.length, 3)
assert.equal(this.clone.array.length, 4)
})
})
suite('nested object', function () {
test('throws type error', function () {
assert.throws(function () {
lunr.utils.clone({
'foo': {
'bar': 1
}
})
}, TypeError)
})
})
})
})

154
mcp-server/node_modules/lunr/test/vector_test.js generated vendored Normal file
View File

@@ -0,0 +1,154 @@
suite('lunr.Vector', function () {
var vectorFromArgs = function () {
var vector = new lunr.Vector
Array.prototype.slice.call(arguments)
.forEach(function (el, i) {
vector.insert(i, el)
})
return vector
}
suite('#magnitude', function () {
test('calculates magnitude of a vector', function () {
var vector = vectorFromArgs(4,5,6)
assert.equal(Math.sqrt(77), vector.magnitude())
})
})
suite('#dot', function () {
test('calculates dot product of two vectors', function () {
var v1 = vectorFromArgs(1, 3, -5),
v2 = vectorFromArgs(4, -2, -1)
assert.equal(3, v1.dot(v2))
})
})
suite('#similarity', function () {
test('calculates the similarity between two vectors', function () {
var v1 = vectorFromArgs(1, 3, -5),
v2 = vectorFromArgs(4, -2, -1)
assert.approximately(v1.similarity(v2), 0.5, 0.01)
})
test('empty vector', function () {
var vEmpty = new lunr.Vector,
v1 = vectorFromArgs(1)
assert.equal(0, vEmpty.similarity(v1))
assert.equal(0, v1.similarity(vEmpty))
})
test('non-overlapping vector', function () {
var v1 = new lunr.Vector([1, 1]),
v2 = new lunr.Vector([2, 1])
assert.equal(0, v1.similarity(v2))
assert.equal(0, v2.similarity(v1))
})
})
suite('#insert', function () {
test('invalidates magnitude cache', function () {
var vector = vectorFromArgs(4,5,6)
assert.equal(Math.sqrt(77), vector.magnitude())
vector.insert(3, 7)
assert.equal(Math.sqrt(126), vector.magnitude())
})
test('keeps items in index specified order', function () {
var vector = new lunr.Vector
vector.insert(2, 4)
vector.insert(1, 5)
vector.insert(0, 6)
assert.deepEqual([6,5,4], vector.toArray())
})
test('fails when duplicate entry', function () {
var vector = vectorFromArgs(4, 5, 6)
assert.throws(function () { vector.insert(0, 44) })
})
})
suite('#upsert', function () {
test('invalidates magnitude cache', function () {
var vector = vectorFromArgs(4,5,6)
assert.equal(Math.sqrt(77), vector.magnitude())
vector.upsert(3, 7)
assert.equal(Math.sqrt(126), vector.magnitude())
})
test('keeps items in index specified order', function () {
var vector = new lunr.Vector
vector.upsert(2, 4)
vector.upsert(1, 5)
vector.upsert(0, 6)
assert.deepEqual([6,5,4], vector.toArray())
})
test('calls fn for value on duplicate', function () {
var vector = vectorFromArgs(4, 5, 6)
vector.upsert(0, 4, function (current, passed) { return current + passed })
assert.deepEqual([8, 5, 6], vector.toArray())
})
})
suite('#positionForIndex', function () {
var vector = new lunr.Vector ([
1, 'a',
2, 'b',
4, 'c',
7, 'd',
11, 'e'
])
test('at the beginning', function () {
assert.equal(0, vector.positionForIndex(0))
})
test('at the end', function () {
assert.equal(10, vector.positionForIndex(20))
})
test('consecutive', function () {
assert.equal(4, vector.positionForIndex(3))
})
test('non-consecutive gap after', function () {
assert.equal(6, vector.positionForIndex(5))
})
test('non-consecutive gap before', function () {
assert.equal(6, vector.positionForIndex(6))
})
test('non-consecutive gave before and after', function () {
assert.equal(8, vector.positionForIndex(9))
})
test('duplicate at the beginning', function () {
assert.equal(0, vector.positionForIndex(1))
})
test('duplicate at the end', function () {
assert.equal(8, vector.positionForIndex(11))
})
test('duplicate consecutive', function () {
assert.equal(4, vector.positionForIndex(4))
})
})
})