-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathfuzzy.test.js
134 lines (130 loc) · 5.65 KB
/
fuzzy.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var fuzzy = fuzzy || require('../lib/fuzzy')
, chai = chai || require('chai')
, expect = chai.expect
, _ = _ || require('underscore');
describe('fuzzy', function(){
describe('.test', function(){
it('should return true when fuzzy match', function(){
expect(fuzzy.test('back', 'imaback')).to.be.True;
expect(fuzzy.test('back', 'bakck')).to.be.True;
expect(fuzzy.test('shig', 'osh kosh modkhigow')).to.be.True;
expect(fuzzy.test('', 'osh kosh modkhigow')).to.be.True;
});
it('should return false when no fuzzy match', function(){
expect(fuzzy.test('back', 'abck')).to.be.False;
expect(fuzzy.test('okmgk', 'osh kosh modkhigow')).to.be.False;
});
});
describe('.simpleFilter', function(){
it('should filter the elements of a string array', function(){
expect(fuzzy.simpleFilter('a', ['a'])).to.eql(['a']);
expect(fuzzy.simpleFilter('ab', ['aba', 'c', 'cacb'])).to.eql(['aba', 'cacb']);
});
});
describe('.match', function(){
it('should return the rendered string and match score', function(){
var results = fuzzy.match('ab', 'ZaZbZ', {pre: '<', post: '>'});
expect(results.rendered).to.equal('Z<a>Z<b>Z');
expect(results).to.include.keys('score');
});
it('should not require a template, returning the string as is', function(){
expect(fuzzy.match('ab', 'ZaZbZ').rendered).to.equal('ZaZbZ');
});
it('should return null on no match', function(){
expect(fuzzy.match('ZEBRA!', 'ZaZbZ')).to.equal(null);
});
it('should return a greater score for consecutive matches of pattern', function(){
var consecutiveScore = fuzzy.match('abcd', 'zabcd').score;
var scatteredScore = fuzzy.match('abcd', 'azbcd').score;
expect(consecutiveScore).to.be.above(scatteredScore);
});
it('should be case insensitive by default', function(){
expect(fuzzy.filter('a', ['A'])[0].string).to.equal('A');
});
it('should take an ignoreCase parameter', function(){
var opts = {caseSensitive: true};
expect(fuzzy.match('Ab', 'aB', opts)).to.equal(null);
opts.caseSensitive = false;
expect(fuzzy.match('AB', 'AB', opts)).to.not.equal(null);
});
xit('should return the same score for matches in the middle as matches at beginning', function(){
// TODO: Dont know how I feel about this. Sublime weights characters that
// appear toward the beginning of the string a bit higher
});
// TODO: implement this test
xit('should prefer consecutive characters even if they come after the first match', function(){
var opts = {pre: '<', post: '>'};
var result = fuzzy.match('bass', 'bodacious bass', opts).rendered;
expect(result).to.equal('bodacious <b><a><s><s>');
});
xit('should prefer consecutive characters in a match even if we need to break up into a substring', function(){
var opts = {pre: '<', post: '>'};
var result = fuzzy.match('reic', 'reactive rice', opts).rendered;
expect(result).to.equal('<r><e>active r<i><c>e');
});
});
describe('.filter', function(){
it('should return list untouched when the pattern is undefined', function() {
var arr = ['aba', 'c', 'cacb'];
var result = fuzzy.filter(undefined, arr);
expect(result).to.equal(arr);
});
it('should return an empty array when the array is undefined', function() {
var result = fuzzy.filter('pattern', undefined);
expect(result).to.deep.equal([]);
});
it('should return an empty array when the array is empty', function() {
var result = fuzzy.filter('pattern', []);
expect(result).to.deep.equal([]);
});
it('should return the index and matching array elements', function(){
var result = fuzzy.filter('ab', ['aba', 'c', 'cacb']);
expect(result).to.have.length(2);
// verify first result
expect(result[0].string).to.equal('aba');
expect(result[0].index).to.equal(0);
expect(result[0]).to.have.property('score');
// verify second result
expect(result[1].string).to.equal('cacb');
expect(result[1].index).to.equal(2);
expect(result[1]).to.have.property('score');
});
it('should use optional template stringing to wrap each element', function(){
var rendered = fuzzy.filter('a', ['a'], {
pre: "tah"
, post: "zah!"
})[0].string;
expect(rendered).to.equal('tahazah!');
rendered = fuzzy.filter('ab', ['cacbc'], {
pre: "<"
, post: ">"
})[0].string;
expect(rendered).to.eql('c<a>c<b>c');
});
it('should use optional func to get string out of array entry', function() {
var arr = [{arg: 'hizzahpooslahp'}, {arg: 'arppg'}];
expect(fuzzy.filter('poop', arr, {
extract: function(original) {
return original.arg;
}
})[0].string).to.equal('hizzahpooslahp');
});
it('should return list untouched when given empty pattern', function(){
// array needs to be over size 10: V8 has stable sort with < 10 elements,
// unstable with > 10 elements
var arr = 'abcdefghjklmnop'.split('');
var results = _.pluck(fuzzy.filter('', arr), 'string');
expect(results).to.eql(arr);
});
it('should weight exact matches the highest', function(){
// array needs to be over size 10: V8 has stable sort with < 10 elements,
// unstable with > 10 elements
var searchString = 'go';
var arr = 'abcdefghjklmnop'.split('');
arr = arr.map(function(item) { return item + 'oo'; });
arr = arr.concat(['good', 'go', 'goofgo', 'ogo']);
var results = _.pluck(fuzzy.filter(searchString, arr), 'string');
expect(results[0]).to.eql(searchString);
});
});
});