Comparing version 2.1.6 to 2.2.0-alpha.1
@@ -28,3 +28,3 @@ { | ||
"serializable", "tis", "twas", "int", "args", "unshift", "plugins", "upsert", | ||
"upserting" | ||
"upserting", "readonly", "baz" | ||
] | ||
@@ -31,0 +31,0 @@ } |
@@ -63,2 +63,8 @@ /*! | ||
* | ||
* Each term also supports a presence modifier. By default a term's presence in document is optional, however | ||
* this can be changed to either required or prohibited. For a term's presence to be required in a document the | ||
* term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and | ||
* optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not | ||
* appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'. | ||
* | ||
* To escape special characters the backslash character '\' can be used, this allows searches to include | ||
@@ -79,2 +85,4 @@ * characters that would normally be considered modifiers, e.g. `foo\~2` will search for a term "foo~2" instead | ||
* hello~2 | ||
* @example <caption>terms with presence modifiers</caption> | ||
* -foo +bar baz | ||
*/ | ||
@@ -137,3 +145,5 @@ | ||
queryVectors = Object.create(null), | ||
termFieldCache = Object.create(null) | ||
termFieldCache = Object.create(null), | ||
requiredMatches = Object.create(null), | ||
prohibitedMatches = Object.create(null) | ||
@@ -179,2 +189,17 @@ fn.call(query, query) | ||
/* | ||
* If a term marked as required does not exist in the tokenSet it is | ||
* impossible for the search to return any matches. We set all the field | ||
* scoped required matches set to empty and stop examining any further | ||
* clauses. | ||
*/ | ||
if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) { | ||
for (var k = 0; k < clause.fields.length; k++) { | ||
var field = clause.fields[k] | ||
requiredMatches[field] = lunr.Set.empty | ||
} | ||
break | ||
} | ||
for (var j = 0; j < expandedTerms.length; j++) { | ||
@@ -201,5 +226,39 @@ /* | ||
matchingDocumentRefs = Object.keys(fieldPosting), | ||
termField = expandedTerm + "/" + field | ||
termField = expandedTerm + "/" + field, | ||
matchingDocumentsSet = new lunr.Set(matchingDocumentRefs) | ||
/* | ||
* if the presence of this term is required ensure that the matching | ||
* documents are added to the set of required matches for this field, | ||
* creating that set if it does not yet exist. | ||
*/ | ||
if (clause.presence == lunr.Query.presence.REQUIRED) { | ||
if (requiredMatches[field] === undefined) { | ||
requiredMatches[field] = lunr.Set.complete | ||
} | ||
requiredMatches[field] = requiredMatches[field].intersect(matchingDocumentsSet) | ||
} | ||
/* | ||
* if the presence of this term is prohibited ensure that the matching | ||
* documents are added to the set of prohibited matches for this field, | ||
* creating that set if it does not yet exist. | ||
*/ | ||
if (clause.presence == lunr.Query.presence.PROHIBITED) { | ||
if (prohibitedMatches[field] === undefined) { | ||
prohibitedMatches[field] = lunr.Set.empty | ||
} | ||
prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet) | ||
/* | ||
* Prohibited matches should not be part of the query vector used for | ||
* similarity scoring and no metadata should be extracted so we continue | ||
* to the next field | ||
*/ | ||
continue | ||
} | ||
/* | ||
* To support field level boosts a query vector is created per | ||
@@ -257,2 +316,22 @@ * field. This vector is populated using the termIndex found for | ||
/** | ||
* Need to combine the field scoped required and prohibited | ||
* matching documents into a global set of required and prohibited | ||
* matches | ||
*/ | ||
var allRequiredMatches = lunr.Set.complete, | ||
allProhibitedMatches = lunr.Set.empty | ||
for (var i = 0; i < this.fields.length; i++) { | ||
var field = this.fields[i] | ||
if (requiredMatches[field]) { | ||
allRequiredMatches = allRequiredMatches.union(requiredMatches[field]) | ||
} | ||
if (prohibitedMatches[field]) { | ||
allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field]) | ||
} | ||
} | ||
var matchingFieldRefs = Object.keys(matchingFields), | ||
@@ -277,2 +356,10 @@ results = [], | ||
if (!allRequiredMatches.contains(docRef)) { | ||
continue | ||
} | ||
if (allProhibitedMatches.contains(docRef)) { | ||
continue | ||
} | ||
if ((docMatch = matches[docRef]) !== undefined) { | ||
@@ -279,0 +366,0 @@ docMatch.score += score |
@@ -99,2 +99,3 @@ lunr.QueryLexer = function (str) { | ||
lunr.QueryLexer.BOOST = 'BOOST' | ||
lunr.QueryLexer.PRESENCE = 'PRESENCE' | ||
@@ -188,2 +189,18 @@ lunr.QueryLexer.lexField = function (lexer) { | ||
// "+" indicates term presence is required | ||
// checking for length to ensure that only | ||
// leading "+" are considered | ||
if (char == "+" && lexer.width() === 1) { | ||
lexer.emit(lunr.QueryLexer.PRESENCE) | ||
return lunr.QueryLexer.lexText | ||
} | ||
// "-" indicates term presence is prohibited | ||
// checking for length to ensure that only | ||
// leading "-" are considered | ||
if (char == "-" && lexer.width() === 1) { | ||
lexer.emit(lunr.QueryLexer.PRESENCE) | ||
return lunr.QueryLexer.lexText | ||
} | ||
if (char.match(lunr.QueryLexer.termSeparator)) { | ||
@@ -190,0 +207,0 @@ return lunr.QueryLexer.lexTerm |
@@ -12,3 +12,3 @@ lunr.QueryParser = function (str, query) { | ||
var state = lunr.QueryParser.parseFieldOrTerm | ||
var state = lunr.QueryParser.parseClause | ||
@@ -38,3 +38,3 @@ while (state) { | ||
lunr.QueryParser.parseFieldOrTerm = function (parser) { | ||
lunr.QueryParser.parseClause = function (parser) { | ||
var lexeme = parser.peekLexeme() | ||
@@ -47,2 +47,4 @@ | ||
switch (lexeme.type) { | ||
case lunr.QueryLexer.PRESENCE: | ||
return lunr.QueryParser.parsePresence | ||
case lunr.QueryLexer.FIELD: | ||
@@ -63,2 +65,39 @@ return lunr.QueryParser.parseField | ||
lunr.QueryParser.parsePresence = function (parser) { | ||
var lexeme = parser.consumeLexeme() | ||
if (lexeme == undefined) { | ||
return | ||
} | ||
switch (lexeme.str) { | ||
case "-": | ||
parser.currentClause.presence = lunr.Query.presence.PROHIBITED | ||
break | ||
case "+": | ||
parser.currentClause.presence = lunr.Query.presence.REQUIRED | ||
break | ||
default: | ||
var errorMessage = "unrecognised presence operator'" + lexeme.str + "'" | ||
throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) | ||
} | ||
var nextLexeme = parser.peekLexeme() | ||
if (nextLexeme == undefined) { | ||
var errorMessage = "expecting term or field, found nothing" | ||
throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end) | ||
} | ||
switch (nextLexeme.type) { | ||
case lunr.QueryLexer.FIELD: | ||
return lunr.QueryParser.parseField | ||
case lunr.QueryLexer.TERM: | ||
return lunr.QueryParser.parseTerm | ||
default: | ||
var errorMessage = "expecting term or field, found '" + nextLexeme.type + "'" | ||
throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end) | ||
} | ||
} | ||
lunr.QueryParser.parseField = function (parser) { | ||
@@ -127,2 +166,5 @@ var lexeme = parser.consumeLexeme() | ||
return lunr.QueryParser.parseBoost | ||
case lunr.QueryLexer.PRESENCE: | ||
parser.nextClause() | ||
return lunr.QueryParser.parsePresence | ||
default: | ||
@@ -129,0 +171,0 @@ var errorMessage = "Unexpected lexeme type '" + nextLexeme.type + "'" |
@@ -40,2 +40,3 @@ /** | ||
*/ | ||
lunr.Query.wildcard = new String ("*") | ||
@@ -47,2 +48,32 @@ lunr.Query.wildcard.NONE = 0 | ||
/** | ||
* Constants for indicating what kind of presence a term must have in matching documents. | ||
* | ||
* @constant | ||
* @enum {number} | ||
* @see lunr.Query~Clause | ||
* @see lunr.Query#clause | ||
* @see lunr.Query#term | ||
* @example <caption>query term with required presence</caption> | ||
* query.term('foo', { presence: lunr.Query.presence.REQUIRED }) | ||
*/ | ||
lunr.Query.presence = { | ||
/** | ||
* Term's presence in a document is optional, this is the default value. | ||
*/ | ||
OPTIONAL: 1, | ||
/** | ||
* Term's presence in a document is required, documents that do not contain | ||
* this term will not be returned. | ||
*/ | ||
REQUIRED: 2, | ||
/** | ||
* Term's presence in a document is prohibited, documents that do contain | ||
* this term will not be returned. | ||
*/ | ||
PROHIBITED: 3 | ||
} | ||
/** | ||
* A single clause in a {@link lunr.Query} contains a term and details on how to | ||
@@ -56,3 +87,4 @@ * match that term against a {@link lunr.Index}. | ||
* @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline. | ||
* @property {number} [wildcard=0] - Whether the term should have wildcards appended or prepended. | ||
* @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended. | ||
* @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents. | ||
*/ | ||
@@ -95,2 +127,6 @@ | ||
if (!('presence' in clause)) { | ||
clause.presence = lunr.Query.presence.OPTIONAL | ||
} | ||
this.clauses.push(clause) | ||
@@ -97,0 +133,0 @@ |
@@ -17,2 +17,3 @@ /* eslint-disable */ | ||
* @see {@link lunr.Pipeline} | ||
* @function | ||
*/ | ||
@@ -19,0 +20,0 @@ lunr.stemmer = (function(){ |
@@ -13,2 +13,3 @@ /*! | ||
* | ||
* @function | ||
* @param {Array} token The token to pass through the filter | ||
@@ -37,2 +38,3 @@ * @returns {lunr.PipelineFunction} | ||
* | ||
* @function | ||
* @implements {lunr.PipelineFunction} | ||
@@ -39,0 +41,0 @@ * @params {lunr.Token} token - A token to check for being a stop word. |
@@ -18,2 +18,3 @@ /*! | ||
* @returns {lunr.Token[]} | ||
* @see {@link lunr.Pipeline} | ||
*/ | ||
@@ -20,0 +21,0 @@ lunr.tokenizer = function (obj) { |
@@ -8,2 +8,3 @@ /*! | ||
* A namespace containing utils for the rest of the lunr library | ||
* @namespace lunr.utils | ||
*/ | ||
@@ -16,3 +17,4 @@ lunr.utils = {} | ||
* @param {String} message The message to be printed. | ||
* @memberOf Utils | ||
* @memberOf lunr.utils | ||
* @function | ||
*/ | ||
@@ -38,3 +40,3 @@ lunr.utils.warn = (function (global) { | ||
* @return {String} string representation of the passed object. | ||
* @memberOf Utils | ||
* @memberOf lunr.utils | ||
*/ | ||
@@ -41,0 +43,0 @@ lunr.utils.asString = function (obj) { |
{ | ||
"name": "lunr", | ||
"description": "Simple full-text search in your browser.", | ||
"version": "2.1.6", | ||
"version": "2.2.0-alpha.1", | ||
"author": "Oliver Nightingale", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
@@ -1,1 +0,1 @@ | ||
{"test_files":["test/builder_test.js","test/match_data_test.js","test/pipeline_test.js","test/query_lexer_test.js","test/query_parser_test.js","test/query_test.js","test/search_test.js","test/serialization_test.js","test/stemmer_test.js","test/stop_word_filter_test.js","test/token_set_test.js","test/token_test.js","test/tokenizer_test.js","test/trimmer_test.js","test/vector_test.js"]} | ||
{"test_files":["test/builder_test.js","test/field_ref_test.js","test/match_data_test.js","test/pipeline_test.js","test/query_lexer_test.js","test/query_parser_test.js","test/query_test.js","test/search_test.js","test/serialization_test.js","test/set_test.js","test/stemmer_test.js","test/stop_word_filter_test.js","test/token_set_test.js","test/token_test.js","test/tokenizer_test.js","test/trimmer_test.js","test/vector_test.js"]} |
@@ -42,2 +42,41 @@ suite('lunr.QueryLexer', function () { | ||
// 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 () { | ||
@@ -112,2 +151,38 @@ setup(function () { | ||
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('separator length > 1', function () { | ||
@@ -234,3 +309,118 @@ setup(function () { | ||
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 () { | ||
@@ -237,0 +427,0 @@ setup(function () { |
@@ -34,2 +34,6 @@ suite('lunr.QueryParser', function () { | ||
test('presence', function () { | ||
assert.equal(lunr.Query.presence.OPTIONAL, this.clause.presence) | ||
}) | ||
test('usePipeline', function () { | ||
@@ -110,2 +114,13 @@ assert.ok(this.clause.usePipeline) | ||
suite('multiple terms with presence', function () { | ||
setup(function () { | ||
this.clauses = parse('+foo +bar') | ||
}) | ||
test('has 2 clause', function () { | ||
debugger | ||
assert.lengthOf(this.clauses, 2) | ||
}) | ||
}) | ||
suite('field without a term', function () { | ||
@@ -343,2 +358,106 @@ test('fails with lunr.QueryParseError', function () { | ||
}) | ||
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) | ||
}) | ||
}) | ||
}) | ||
@@ -345,0 +464,0 @@ |
@@ -33,16 +33,32 @@ suite('search', function () { | ||
suite('one match', function () { | ||
setup(function () { | ||
this.results = this.idx.search('scarlett') | ||
}) | ||
var assertions = function () { | ||
test('one result returned', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('one result returned', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('document c matches', function () { | ||
assert.equal('c', this.results[0].ref) | ||
}) | ||
test('document c matches', function () { | ||
assert.equal('c', this.results[0].ref) | ||
test('matching term', function () { | ||
assert.sameMembers(['scarlett'], Object.keys(this.results[0].matchData.metadata)) | ||
}) | ||
} | ||
suite('#seach', function () { | ||
setup(function () { | ||
this.results = this.idx.search('scarlett') | ||
}) | ||
assertions() | ||
}) | ||
test('matching term', function () { | ||
assert.sameMembers(['scarlett'], Object.keys(this.results[0].matchData.metadata)) | ||
suite('#query', function () { | ||
setup(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('scarlett') | ||
}) | ||
}) | ||
assertions() | ||
}) | ||
@@ -541,2 +557,237 @@ }) | ||
}) | ||
suite('term presence', function () { | ||
suite('prohibited', function () { | ||
suite('match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('two results found', function () { | ||
assert.lengthOf(this.results, 2) | ||
}) | ||
test('matching documents returned', function () { | ||
assert.equal('b', this.results[0].ref) | ||
assert.equal('c', this.results[1].ref) | ||
}) | ||
test('matching terms returned', function () { | ||
assert.sameMembers(['green'], Object.keys(this.results[0].matchData.metadata)) | ||
assert.sameMembers(['green'], Object.keys(this.results[1].matchData.metadata)) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('candlestick', { presence: lunr.Query.presence.PROHIBITED }) | ||
q.term('green', { presence: lunr.Query.presence.OPTIONAL }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('-candlestick green') | ||
})) | ||
}) | ||
suite('no match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('no matches', function () { | ||
assert.lengthOf(this.results, 0) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('green', { presence: lunr.Query.presence.PROHIBITED }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('-green') | ||
})) | ||
}) | ||
suite('no matching term', function () { | ||
setup(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('qwertyuiop', { presence: lunr.Query.presence.PROHIBITED }) | ||
}) | ||
}) | ||
// TODO: what is the right behaviour here? | ||
// logically it _should_ return all results, but is that useful? It would | ||
// require a bunch of extra work to return a result set that isn't very useful. | ||
// Perhaps instead it should just mark queries that only have prohibited clauses | ||
// as invalid? | ||
test('all results returned?') | ||
}) | ||
suite('field match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('one result found', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('matching documents returned', function () { | ||
assert.equal('c', this.results[0].ref) | ||
}) | ||
test('matching terms returned', function () { | ||
assert.sameMembers(['plumb'], Object.keys(this.results[0].matchData.metadata)) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('plant', { presence: lunr.Query.presence.PROHIBITED, fields: ['title'] }) | ||
q.term('plumb', { presence: lunr.Query.presence.OPTIONAL }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('-title:plant plumb') | ||
})) | ||
}) | ||
}) | ||
suite('required', function () { | ||
suite('match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('one result found', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('matching documents returned', function () { | ||
assert.equal('a', this.results[0].ref) | ||
}) | ||
test('matching terms returned', function () { | ||
assert.sameMembers(['candlestick', 'green'], Object.keys(this.results[0].matchData.metadata)) | ||
}) | ||
} | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search("+candlestick green") | ||
})) | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('candlestick', { presence: lunr.Query.presence.REQUIRED }) | ||
q.term('green', { presence: lunr.Query.presence.OPTIONAL }) | ||
}) | ||
})) | ||
}) | ||
suite('no match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('no matches', function () { | ||
assert.lengthOf(this.results, 0) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('mustard', { presence: lunr.Query.presence.REQUIRED }) | ||
q.term('plant', { presence: lunr.Query.presence.REQUIRED }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('+mustard +plant') | ||
})) | ||
}) | ||
suite('no matching term', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('no matches', function () { | ||
assert.lengthOf(this.results, 0) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('qwertyuiop', { presence: lunr.Query.presence.REQUIRED }) | ||
q.term('green', { presence: lunr.Query.presence.OPTIONAL }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('+qwertyuiop green') | ||
})) | ||
}) | ||
suite('field match', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('one result found', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('matching documents returned', function () { | ||
assert.equal('b', this.results[0].ref) | ||
}) | ||
test('matching terms returned', function () { | ||
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata)) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('plant', { presence: lunr.Query.presence.REQUIRED, fields: ['title'] }) | ||
q.term('green', { presence: lunr.Query.presence.OPTIONAL }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('+title:plant green') | ||
})) | ||
}) | ||
}) | ||
suite('combined', function () { | ||
var assertions = function (fn) { | ||
setup(fn) | ||
test('one result found', function () { | ||
assert.lengthOf(this.results, 1) | ||
}) | ||
test('matching documents returned', function () { | ||
assert.equal('b', this.results[0].ref) | ||
}) | ||
test('matching terms returned', function () { | ||
assert.sameMembers(['plant', 'green'], Object.keys(this.results[0].matchData.metadata)) | ||
}) | ||
} | ||
suite('#query', assertions(function () { | ||
this.results = this.idx.query(function (q) { | ||
q.term('plant', { presence: lunr.Query.presence.REQUIRED }) | ||
q.term('green', { presence: lunr.Query.presence.OPTIONAL }) | ||
q.term('office', { presence: lunr.Query.presence.PROHIBITED }) | ||
}) | ||
})) | ||
suite('#search', assertions(function () { | ||
this.results = this.idx.search('+plant green -office') | ||
})) | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is too big to display
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
660007
86
20014
1