From b7110fa836a17d1e8dacf35961e3858b9dc8d6df Mon Sep 17 00:00:00 2001 From: Dave Newton Date: Mon, 9 May 2016 09:32:58 -0400 Subject: [PATCH] Add support for `allowDashes` Add support for `allowDashes` as an option, next to other **nlcst-normalize** configuration, to control whether hyphens are normalised. Closes GH-3. --- .jscs.json | 2 +- index.js | 15 ++++-- package.json | 2 +- readme.md | 7 ++- test.js | 138 +++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 153 insertions(+), 11 deletions(-) diff --git a/.jscs.json b/.jscs.json index 0bcf33b..a1fd128 100644 --- a/.jscs.json +++ b/.jscs.json @@ -9,7 +9,7 @@ "requireQuotedKeysInObjects": true, "disallowQuotedKeysInObjects": false, "maximumLineLength": { - "value": 79, + "value": 80, "allExcept": [ "regex", "urlComments" diff --git a/index.js b/index.js index 7855bbc..2c85b8e 100644 --- a/index.js +++ b/index.js @@ -49,20 +49,27 @@ var T_WHITE_SPACE = 'WhiteSpaceNode'; function search(tree, phrases, handler, options) { var settings = options || {}; var apos = settings.allowApostrophes || options; + var dashes = settings.allowDashes || false; var literals = settings.allowLiterals; var byWord = {}; + var config; var length; var index; var key; var firstWord; + config = { + 'allowApostrophes': apos, + 'allowDashes': dashes + }; + /** * Handle a phrase. * * @param {string} phrase - Phrase to search for. */ function handlePhrase(phrase) { - firstWord = normalize(phrase.split(C_SPACE, 1)[0], apos); + firstWord = normalize(phrase.split(C_SPACE, 1)[0], config); if (has.call(byWord, firstWord)) { byWord[firstWord].push(phrase); @@ -147,7 +154,9 @@ function search(tree, phrases, handler, options) { if ( !node || node.type !== T_WORD || - normalize(expression[index], apos) !== normalize(node, apos) + normalize(expression[index], config) + !== + normalize(node, config) ) { return null; } @@ -178,7 +187,7 @@ function search(tree, phrases, handler, options) { return; } - word = normalize(node, apos); + word = normalize(node, config); phrases = has.call(byWord, word) ? byWord[word] : []; length = phrases.length; index = -1; diff --git a/package.json b/package.json index 4e90a98..4ac5b79 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ ], "dependencies": { "nlcst-is-literal": "^1.0.0", - "nlcst-normalize": "^1.1.0", + "nlcst-normalize": "^2.0.0", "unist-util-visit": "^1.0.0" }, "devDependencies": { diff --git a/readme.md b/readme.md index a4c21bf..a8883a6 100644 --- a/readme.md +++ b/readme.md @@ -84,12 +84,15 @@ Search for patterns in an NLCST tree. word is [normalize][]d to remove casing, apostrophes, and dashes; * `allowApostrophes` (`boolean`, default: `false`) - — Do not strip apostrophes (but [normalize][] them). + — Configuration for [**nlcst-normalize**][normalize]); * `options` (`Object`) — Configuration: * `allowApostrophes` (`boolean`, default: `false`) - — See `allowApostrophes` above; + — Configuration for [**nlcst-normalize**][normalize]); + + * `allowDashes` (`boolean`, default: `false`) + — Configuration for [**nlcst-normalize**][normalize]); * `allowLiterals` (`boolean`, default: `false`) — Include [literal][] phrases. diff --git a/test.js b/test.js index 28ac576..e22f266 100644 --- a/test.js +++ b/test.js @@ -190,6 +190,19 @@ var tree = { 'value': 'hell' } ] + }, + { + 'type': 'WhiteSpaceNode', + 'value': ' ' + }, + { + 'type': 'WordNode', + 'children': [ + { + 'type': 'TextNode', + 'value': 'selfservice' + } + ] } ] }; @@ -199,7 +212,7 @@ var tree = { */ test('search(tree, patterns, handle)', function (t) { - t.plan(42); + t.plan(68); t.throws( function () { @@ -274,7 +287,7 @@ test('search(tree, patterns, handle)', function (t) { t.doesNotThrow(function () { search(tree, ['or that']); - }, 'should not include non-word and non-white-space nodes'); + }, 'shouldn’t include non-word and non-white-space nodes'); var phrases = ['that or this', 'that']; @@ -292,13 +305,130 @@ test('search(tree, patterns, handle)', function (t) { t.equal(phrase, match[3], 'should pass the phrase (phrases)'); }); + /* + * Handler function is only invoked if match is found + * search will throw if a match is found and no handler + * is provided the tree contains “hell” but not “he’ll” + * or “he'll”. + */ + + t.throws(function () { + search(tree, ['hell'], null); + }, 'should find non-apostrophe words when `allowApostrophes` is absent'); + + t.throws(function () { + search(tree, ['he’ll'], null); + }, 'should find smart apostrophe words when `allowApostrophes` is absent'); + + t.throws(function () { + search(tree, ['he\'ll'], null); + }, 'should find dumb apostrophe words when `allowApostrophes` is absent'); + + t.throws(function () { + search(tree, ['hell'], null, true); + }, 'should find non-apostrophe words when `allowApostrophes` is true'); + t.doesNotThrow(function () { search(tree, ['he’ll'], null, true); - }, 'should not find non-apostrophe words when `allowApostrophes` is true'); + }, 'shouldn’t find smart apostrophe words when `allowApostrophes` is true'); + + t.doesNotThrow(function () { + search(tree, ['he\'ll'], null, true); + }, 'shouldn’t find dumb apostrophe words when `allowApostrophes` is true'); + + t.throws(function () { + search(tree, ['hell'], null, false); + }, 'should find non-apostrophe words when `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['he’ll'], null, false); + }, 'should find smart apostrophe words when `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['he\'ll'], null, false); + }, 'should find dumb apostrophe words when `allowApostrophes` is false'); + + /* + * The tree contains “selfservice” but not “self-service” + */ + + /* jscs:disable maximumLineLength */ + t.throws(function () { + search(tree, ['selfservice'], null); + }, 'should find non-dash words when `allowDashes` is absent and `allowApostrophes` is absent'); + + t.throws(function () { + search(tree, ['self-service'], null); + }, 'should find dash words when `allowDashes` is absent and `allowApostrophes` is absent'); + + t.throws(function () { + search(tree, ['selfservice'], null, false); + }, 'should find non-dash words when `allowDashes` is absent and `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['self-service'], null, false); + }, 'should find dash words when `allowDashes` is absent and `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['selfservice'], null, true); + }, 'should find non-dash words when `allowDashes` is absent and `allowApostrophes` is true'); + + t.throws(function () { + search(tree, ['self-service'], null, true); + }, 'should find dash words when `allowDashes` is absent and `allowApostrophes` is true'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowDashes': true}); + }, 'should find non-dash words when `allowDashes` is true'); + + t.doesNotThrow(function () { + search(tree, ['self-service'], null, {'allowDashes': true}); + }, 'shouldn’t find dash words when `allowDashes` is true'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowDashes': false}); + }, 'should find non-dash words when `allowDashes` is false'); + + t.throws(function () { + search(tree, ['self-service'], null, {'allowDashes': false}); + }, 'should find dash words when `allowDashes` is false'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowApostrophes': false, 'allowDashes': true}); + }, 'should find non-dash words when `allowDashes` is true and `allowApostrophes` is false'); + + t.doesNotThrow(function () { + search(tree, ['self-service'], null, {'allowApostrophes': false, 'allowDashes': true}); + }, 'shouldn’t find dash words when `allowDashes` is true and `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowApostrophes': false, 'allowDashes': false}); + }, 'should find non-dash words when `allowDashes` is false and `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['self-service'], null, {'allowApostrophes': false, 'allowDashes': false}); + }, 'should find dash words when `allowDashes` is false and `allowApostrophes` is false'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowApostrophes': true, 'allowDashes': true}); + }, 'should find non-dash words when `allowDashes` is true and `allowApostrophes` is true'); + + t.doesNotThrow(function () { + search(tree, ['self-service'], null, {'allowApostrophes': true, 'allowDashes': true}); + }, 'shouldn’t find dash words when `allowDashes` is true and `allowApostrophes` is true'); + + t.throws(function () { + search(tree, ['selfservice'], null, {'allowApostrophes': true, 'allowDashes': false}); + }, 'should find non-dash words when `allowDashes` is false and `allowApostrophes` is true'); + + t.throws(function () { + search(tree, ['self-service'], null, {'allowApostrophes': true, 'allowDashes': false}); + }, 'should find dash words when `allowDashes` is false and `allowApostrophes` is true'); + /* jscs:enable maximumLineLength */ t.doesNotThrow(function () { search(tree, ['mellow']); - }, 'should not find literals by default'); + }, 'shouldn’t find literals by default'); search(tree, ['mellow'], function () { t.pass('should find literals when given `allowLiterals`');