Fuse/test/fuse.test.js
ErikLarsson82 b1fe7cc67b False positive matches when pattern.length > 32 #136 #254 bugfix (#333)
* Initial tests (that fail) for #136

* Fix for maximum integer overflow in signed 32 bit number by applying ceiling. Also tests. Issue #136
2019-10-30 23:14:51 -07:00

1035 lines
29 KiB
JavaScript

const Fuse = require('../dist/fuse')
const books = require('./fixtures/books.json')
const deepValue = require('../src/helpers/deep_value')
const verbose = false
const defaultList = ['Apple', 'Orange', 'Banana']
const defaultOptions = {
location: 0,
distance: 100,
threshold: 0.6,
maxPatternLength: 32,
isCaseSensitive: false,
tokenSeparator: / +/g,
findAllMatches: false,
minMatchCharLength: 1,
id: null,
keys: [],
shouldSort: true,
getFn: deepValue,
sortFn: (a, b) => (a.score - b.score),
tokenize: false,
matchAllTokens: false,
includeMatches: false,
includeScore: false,
verbose
}
const setup = (itemList, overwriteOptions) => {
const list = itemList || defaultList
const options = {...defaultOptions, ...overwriteOptions}
return new Fuse(list, options)
}
describe('Flat list of strings: ["Apple", "Orange", "Banana"]', () => {
let fuse
beforeEach(() => fuse = setup())
it('should have the correct configuration', () => {
const expected = {list: defaultList, options: defaultOptions}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Apple"', () => {
let result
beforeEach(() => result = fuse.search('Apple'))
test('we get a list of exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the index 0, representing ["Apple"]', () => {
expect(result[0]).toBe(0)
})
})
describe('When performing a fuzzy search for the term "ran"', () => {
let result
beforeEach(() => result = fuse.search('ran'))
test('we get a list of containing 2 items', () => {
expect(result).toHaveLength(2)
})
test('whose values represent the indices of ["Orange", "Banana"]', () => {
expect(result[0]).toBe(1)
expect(result[1]).toBe(2)
})
})
describe('When performing a fuzzy search for the term "nan"', () => {
let result
beforeEach(() => result = fuse.search('nan'))
test('we get a list of containing 2 items', () => {
expect(result).toHaveLength(2)
})
test('whose values represent the indices of ["Banana", "Orange"]', () => {
expect(result[0]).toBe(2)
expect(result[1]).toBe(1)
})
})
describe('When performing a fuzzy search for the term "nan" with a limit of 1 result', () => {
let result
beforeEach(() => result = fuse.search('nan', {limit: 1}))
test('we get a list of containing 1 item: [2]', () => {
expect(result).toHaveLength(1)
})
test('whose values represent the indices of ["Banana", "Orange"]', () => {
expect(result[0]).toBe(2)
})
})
})
describe('List of books - searching "title" and "author"', () => {
let fuse
beforeEach(() => fuse = setup(books, {keys: ['title', 'author'], tokenize: true}))
it('should have the correct configuration', () => {
const expected = {list: books, options: {...defaultOptions, keys: ['title', 'author'], tokenize: true}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "HTML5"', () => {
let result
beforeEach(() => result = fuse.search('HTML5'))
test('we get a list of containing 3 items', () => {
expect(result).toHaveLength(3)
})
test('and the first item has the matching key/value pairs', () => {
expect(result[0]).toMatchObject({title: 'HTML5', author: 'Remy Sharp'})
})
})
describe('When searching with pattern length over 32', () => {
let result
beforeEach(() => result = fuse.search(Array(16).fill('HTML5').join(' ')))
test('we get a list of containing 3 items', () => {
expect(result).toHaveLength(3)
})
test('and the first item has the matching key/value pairs', () => {
expect(result[0]).toMatchObject({title: 'HTML5', author: 'Remy Sharp'})
})
})
describe('When searching for the term "Jeeves Woodhouse"', () => {
let result
beforeEach(() => result = fuse.search('Jeeves Woodhouse'))
test('we get a list of containing 6 items', () => {
expect(result).toHaveLength(6)
})
test('which are all the books written by "P.D. Woodhouse"', () => {
const expectedResult = [
{title: 'Right Ho Jeeves', author: 'P.D. Woodhouse'},
{title: 'Thank You Jeeves', author: 'P.D. Woodhouse'},
{title: 'The Code of the Wooster', author: 'P.D. Woodhouse'},
{title: 'The Lock Artist', author: 'Steve Hamilton'},
{title: 'the wooster code', author: 'aa'},
{title: 'The code of the wooster', author: 'aa'}
]
expect(result).toStrictEqual(expectedResult)
})
})
describe('When searching for the term "brwn"', () => {
let result
beforeEach(() => result = fuse.search('brwn'))
test('we get a list containing at least 3 items', () => {
expect(result.length).toBeGreaterThanOrEqual(3)
})
test('and the first 3 items should be all the books written by Dan Brown"', () => {
expect(result[0]).toMatchObject({
'title': 'The DaVinci Code',
'author': 'Dan Brown'
})
expect(result[1]).toMatchObject({
'title': 'Angels & Demons',
'author': 'Dan Brown'
})
expect(result[2]).toMatchObject({
'title': 'The Lost Symbol',
'author': 'Dan Brown'
})
})
})
})
describe('Deep key search, with ["title", "author.firstName"]', () => {
const customBookList = [{
title: "Old Man's War",
author: {firstName: 'John', lastName: 'Scalzi'}
}, {
title: 'The Lock Artist',
author: {firstName: 'Steve', lastName: 'Hamilton'}
}, {title: 'HTML5'}, {title: 'A History of England', author: {firstName: 1066, lastName: 'Hastings'}}]
let fuse
beforeEach(() => fuse = setup(customBookList, {keys: ['title', 'author.firstName']}))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, keys: ['title', 'author.firstName']}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing at least 1 item', () => {
expect(result.length).toBeGreaterThanOrEqual(1)
})
test('and the first item has the matching key/value pairs', () => {
expect(result[0]).toMatchObject({
title: 'The Lock Artist',
author: {firstName: 'Steve', lastName: 'Hamilton'}
})
})
})
describe('When searching for the term "106"', () => {
let result
beforeEach(() => result = fuse.search('106'))
test('we get a list of exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value matches', () => {
expect(result[0]).toMatchObject({
title: 'A History of England',
author: {firstName: 1066, lastName: 'Hastings'}
})
})
})
})
describe('Custom search function, with ["title", "author.firstName"]', () => {
const customBookList = [{
title: "Old Man's War",
author: {
firstName: 'John',
lastName: 'Scalzi'
}
}, {
title: 'The Lock Artist',
author: {
firstName: 'Steve',
lastName: 'Hamilton'
}
}]
const customOptions = {
keys: ['title', 'author.firstName'],
getFn: (obj) => {
if (!obj) return null
obj = obj.author.lastName
return obj
}
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Hmlt"', () => {
let result
beforeEach(() => result = fuse.search('Hmlt'))
test('we get a list containing at least 1 item', () => {
expect(result.length).toBeGreaterThanOrEqual(1)
})
test('and the first item has the matching key/value pairs', () => {
expect(result[0]).toMatchObject({
title: 'The Lock Artist',
author: {firstName: 'Steve', lastName: 'Hamilton'}
})
})
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list of exactly 0 items', () => {
expect(result).toHaveLength(0)
})
})
})
describe('Include score in result list: ["Apple", "Orange", "Banana"]', () => {
let fuse
beforeEach(() => fuse = setup(defaultList, {includeScore: true}))
it('should have the correct configuration', () => {
const expected = {list: defaultList, options: {...defaultOptions, includeScore: true}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Apple"', () => {
let result
beforeEach(() => result = fuse.search('Apple'))
test('we get a list of exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the index 0, representing ["Apple"]', () => {
expect(result[0].item).toBe(0)
expect(result[0].score).toBe(0)
})
})
describe('When performing a fuzzy search for the term "ran"', () => {
let result
beforeEach(() => result = fuse.search('ran'))
test('we get a list of containing 2 items', () => {
expect(result).toHaveLength(2)
})
test('whose values represent the indices, and have non-zero scores', () => {
expect(result[0].item).toBe(1)
expect(result[0].score).not.toBe(0)
expect(result[1].item).toBe(2)
expect(result[1].score).not.toBe(0)
})
})
})
describe('Only include ID in result list, with "ISBN"', () => {
const customBookList = [{
ISBN: '0765348276',
title: "Old Man's War",
author: 'John Scalzi'
}, {
ISBN: '0312696957',
title: 'The Lock Artist',
author: 'Steve Hamilton'
}]
const customOptions = {
keys: ['title', 'author'],
id: 'ISBN'
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(result[0]).toBe('0312696957')
})
})
})
describe('Include both ID and score in results list', () => {
const customBookList = [{
ISBN: '0765348276',
title: "Old Man's War",
author: 'John Scalzi'
}, {
ISBN: '0312696957',
title: 'The Lock Artist',
author: 'Steve Hamilton'
}]
const customOptions = {
keys: ['title', 'author'],
id: 'ISBN',
includeScore: true
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(result[0].item).toBe('0312696957')
})
test('and has a score that is not zero', () => {
expect(result[0].score).not.toBe(0)
})
})
})
describe('Search when IDs are numbers', () => {
const customBookList = [{
ISBN: 1111,
title: "Old Man's War",
author: 'John Scalzi'
}, {
ISBN: 2222,
title: 'The Lock Artist',
author: 'Steve Hamilton'
}]
const customOptions = {
keys: ['title', 'author'],
id: 'ISBN',
includeScore: true
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(result[0].item).toBe('2222')
})
test('and has a score that is not zero', () => {
expect(result[0].score).not.toBe(0)
})
})
})
describe('Recurse into arrays', () => {
const customBookList = [{
'ISBN': '0765348276',
'title': "Old Man's War",
'author': 'John Scalzi',
'tags': ['fiction']
}, {
'ISBN': '0312696957',
'title': 'The Lock Artist',
'author': 'Steve Hamilton',
'tags': ['fiction']
}, {
'ISBN': '0321784421',
'title': 'HTML5',
'author': 'Remy Sharp',
'tags': ['web development', 'nonfiction']
}]
const customOptions = {
keys: ['tags'],
id: 'ISBN',
threshold: 0,
includeMatches: true
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the tag "nonfiction"', () => {
let result
beforeEach(() => result = fuse.search('nonfiction'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(result[0].item).toBe('0321784421')
})
test('with matched tag provided', () => {
const {matches} = result[0]
expect(matches[0]).toMatchObject({
key: 'tags',
arrayIndex: 1,
value: 'nonfiction',
indices: [[0, 9]]
})
})
})
})
describe('Recurse into objects in arrays', () => {
const customBookList = [{
'ISBN': '0765348276',
'title': "Old Man's War",
'author': {
'name': 'John Scalzi',
'tags': [{
value: 'American'
}]
}
}, {
'ISBN': '0312696957',
'title': 'The Lock Artist',
'author': {
'name': 'Steve Hamilton',
'tags': [{
value: 'American'
}]
}
}, {
'ISBN': '0321784421',
'title': 'HTML5',
'author': {
'name': 'Remy Sharp',
'tags': [{
value: 'British'
}]
}
}]
const customOptions = {
keys: ['author.tags.value'],
id: 'ISBN',
threshold: 0
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the author tag "British"', () => {
let result
beforeEach(() => result = fuse.search('British'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(result[0]).toBe('0321784421')
})
})
})
describe('Searching by ID', () => {
const customBookList = [{
'ISBN': 'A',
'title': "Old Man's War",
'author': 'John Scalzi'
}, {
'ISBN': 'B',
'title': 'The Lock Artist',
'author': 'Steve Hamilton'
}]
const customOptions = {
keys: ['title', 'author'],
id: 'ISBN'
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(typeof result[0]).toBe('string')
expect(result[0]).toBe('B')
})
})
})
describe('Searching by nested ID', () => {
const customBookList = [{
'ISBN': {'name': 'A'},
'title': "Old Man's War",
'author': 'John Scalzi'
}, {
'ISBN': {'name': 'B'},
'title': 'The Lock Artist',
'author': 'Steve Hamilton'
}]
const customOptions = {
keys: ['title', 'author'],
id: 'ISBN.name'
}
let fuse
beforeEach(() => fuse = setup(customBookList, customOptions))
it('should have the correct configuration', () => {
const expected = {list: customBookList, options: {...defaultOptions, ...customOptions}}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Stve"', () => {
let result
beforeEach(() => result = fuse.search('Stve'))
test('we get a list containing exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the ISBN of the book', () => {
expect(typeof result[0]).toBe('string')
expect(result[0]).toBe('B')
})
})
})
describe('Set new list on Fuse', () => {
const vegetables = ['Onion', 'Lettuce', 'Broccoli']
let fuse
beforeEach(() => {
fuse = setup()
fuse.setCollection(vegetables)
return fuse
})
it('should have the correct configuration', () => {
const expected = {list: vegetables, options: defaultOptions}
expect(fuse).toMatchObject(expected)
})
describe('When searching for the term "Lettuce"', () => {
let result
beforeEach(() => result = fuse.search('Lettuce'))
test('we get a list of exactly 1 item', () => {
expect(result).toHaveLength(1)
})
test('whose value is the index 0, representing ["Apple"]', () => {
expect(result[0]).toBe(1)
})
})
})
describe('Weighted search', () => {
const customBookList = [
{
title: "Old Man's War fiction",
author: 'John X',
tags: ['war']
},
{
title: 'Right Ho Jeeves',
author: 'P.D. Mans',
tags: ['fiction', 'war']
},
{
title: 'The life of Jane',
author: 'John Smith',
tags: ['john', 'smith']
},
{
title: 'John Smith',
author: 'Steve Pearson',
tags: ['steve', 'pearson']
}
]
describe('When searching for the term "John Smith" with author weighted higher', () => {
const customOptions = {
keys: [
{name: 'title', weight: 0.3},
{name: 'author', weight: 0.7}
]
}
let fuse
let result
beforeEach(() => {
fuse = setup(customBookList, customOptions)
return result = fuse.search('John Smith')
})
test('We get the the exactly matching object', () => {
expect(result[0]).toMatchObject({title: 'The life of Jane', author: 'John Smith', tags: ['john', 'smith']})
})
})
describe('When searching for the term "John Smith" with title weighted higher', () => {
const customOptions = {
keys: [
{name: 'title', weight: 0.7},
{name: 'author', weight: 0.3}
]
}
let fuse
let result
beforeEach(() => {
fuse = setup(customBookList, customOptions)
return result = fuse.search('John Smith')
})
test('We get the the exactly matching object', () => {
expect(result[0]).toMatchObject({title: 'John Smith', author: 'Steve Pearson', tags: ['steve', 'pearson']})
})
})
describe('When searching for the term "Man", where the author is weighted higher than title', () => {
const customOptions = {
keys: [
{name: 'title', weight: 0.3},
{name: 'author', weight: 0.7}
]
}
let fuse
let result
beforeEach(() => {
fuse = setup(customBookList, customOptions)
return result = fuse.search('Man')
})
test('We get the the exactly matching object', () => {
expect(result[0]).toMatchObject({title: 'Right Ho Jeeves', author: 'P.D. Mans', tags: ['fiction', 'war']})
})
})
describe('When searching for the term "Man", where the title is weighted higher than author', () => {
const customOptions = {
keys: [
{name: 'title', weight: 0.7},
{name: 'author', weight: 0.3}
]
}
let fuse
let result
beforeEach(() => {
fuse = setup(customBookList, customOptions)
return result = fuse.search('Man')
})
test('We get the the exactly matching object', () => {
expect(result[0]).toMatchObject({title: "Old Man's War fiction", author: 'John X', tags: ['war']})
})
})
describe('When searching for the term "War", where tags are weighted higher than all other keys', () => {
const customOptions = {
keys: [
{name: 'title', weight: 0.8},
{name: 'author', weight: 0.3},
{name: 'tags', weight: 0.9}
]
}
let fuse
let result
beforeEach(() => {
fuse = setup(customBookList, customOptions)
return result = fuse.search('War')
})
test('We get the the exactly matching object', () => {
expect(result[0]).toMatchObject({title: "Old Man's War fiction", author: 'John X', tags: ['war']})
})
})
})
describe('Search location', () => {
const customList = [{name: 'Hello World'}]
const customOptions = {
keys: ['name'],
includeScore: true,
includeMatches: true
}
let fuse
beforeEach(() => fuse = setup(customList, customOptions))
describe('When searching for the term "wor"', () => {
let result
let matches
beforeEach(() => {
result = fuse.search('wor')
return matches = result[0].matches
})
test('We get a list whose indices are found', () => {
expect(matches[0].indices[0]).toEqual([4, 4])
expect(matches[0].indices[1]).toEqual([6, 8])
})
test('with original text values', () => {
expect(matches[0].value).toBe('Hello World')
})
})
})
describe('Search with match all tokens', () => {
const customList = [
'AustralianSuper - Corporate Division',
'Aon Master Trust - Corporate Super',
'Promina Corporate Superannuation Fund',
'Workforce Superannuation Corporate',
'IGT (Australia) Pty Ltd Superannuation Fund'
]
let fuse
beforeEach(() => fuse = setup(customList, {tokenize: true}))
describe('When searching for the term "Australia"', () => {
let result
beforeEach(() => result = fuse.search('Australia'))
test('We get a list containing exactly 2 items', () => {
expect(result).toHaveLength(2)
})
test('whose items represent the indices of "AustralianSuper - Corporate Division" and "IGT (Australia) Pty Ltd Superannuation Fund"', () => {
expect(result).toContain(0)
expect(result).toContain(4)
})
})
describe('When searching for the term "corporate"', () => {
let result
beforeEach(() => result = fuse.search('corporate'))
test('We get a list containing exactly 4 items', () => {
expect(result).toHaveLength(4)
})
test('whose items represent the indices of "AustralianSuper - Corporate Division", "Aon Master Trust - Corporate Super", "Promina Corporate Superannuation Fund" and "Workforce Superannuation Corporate"', () => {
expect(result).toContain(0)
expect(result).toContain(1)
expect(result).toContain(2)
expect(result).toContain(3)
})
})
})
describe('Searching with default options', () => {
const customList = ['t te tes test tes te t']
let fuse
beforeEach(() => fuse = new Fuse(customList, {includeMatches: true}))
describe('When searching for the term "test"', () => {
let result
beforeEach(() => result = fuse.search('test'))
test('We get a match containing 4 indices', () => {
expect(result[0].matches[0].indices).toHaveLength(4)
})
test('and the first index is a single character', () => {
expect(result[0].matches[0].indices[0][0]).toBe(0)
expect(result[0].matches[0].indices[0][1]).toBe(0)
})
})
test('When the seach pattern is longer than maxPatternLength and contains RegExp special characters', () => {
const resultThunk = jest.fn(() => fuse.search('searching with a sufficiently long string sprinkled with ([ )] *+^$ etc.'))
resultThunk()
expect(resultThunk).toHaveBeenCalledTimes(1)
expect(resultThunk).not.toThrow()
})
})
describe('Searching with findAllMatches', () => {
const customList = ['t te tes test tes te t']
let fuse
beforeEach(() => fuse = new Fuse(customList, {includeMatches: true, findAllMatches: true}))
describe('When searching for the term "test"', () => {
let result
beforeEach(() => result = fuse.search('test'))
test('We get a match containing 7 indices', () => {
expect(result[0].matches[0].indices).toHaveLength(7)
})
test('and the first index is a single character', () => {
expect(result[0].matches[0].indices[0][0]).toBe(0)
expect(result[0].matches[0].indices[0][1]).toBe(0)
})
})
})
describe('Searching with minCharLength', () => {
const customList = ['t te tes test tes te t']
let fuse
beforeEach(() => fuse = new Fuse(customList, {includeMatches: true, minMatchCharLength: 2}))
describe('When searching for the term "test"', () => {
let result
beforeEach(() => result = fuse.search('test'))
test('We get a match containing 3 indices', () => {
expect(result[0].matches[0].indices).toHaveLength(3)
})
test('and the first index is a single character', () => {
expect(result[0].matches[0].indices[0][0]).toBe(2)
expect(result[0].matches[0].indices[0][1]).toBe(3)
})
})
describe('When searching for a string shorter than minMatchCharLength', () => {
let result
beforeEach(() => result = fuse.search('t'))
test('We get a result with no matches', () => {
expect(result).toHaveLength(1)
expect(result[0].matches).toHaveLength(0)
})
})
})
describe('Sorted search results', () => {
const customList = [
{
title: 'Right Ho Jeeves',
author: {firstName: 'P.D', lastName: 'Woodhouse'}
},
{
title: 'The Code of the Wooster',
author: {firstName: 'P.D', lastName: 'Woodhouse'}
},
{
title: 'Thank You Jeeves',
author: {firstName: 'P.D', lastName: 'Woodhouse'}
}
]
const customOptions = {
keys: ['title', 'author.firstName', 'author.lastName']
}
let fuse
beforeEach(() => fuse = new Fuse(customList, customOptions))
describe('When searching for the term "wood"', () => {
let result
beforeEach(() => result = fuse.search('wood'))
test('We get the properly ordered results', () => {
expect(result[0].title).toBe('The Code of the Wooster')
expect(result[1].title).toBe('Right Ho Jeeves')
expect(result[2].title).toBe('Thank You Jeeves')
})
})
})
describe('Searching through a deeply nested object', () => {
const customList = {}
const customOptions = {
includeMatches: true,
minMatchCharLength: 2
}
let fuse
customList.o = customList
beforeEach(() => fuse = new Fuse(customList, customOptions))
describe('When working with a deeply nested JSON data structure', () => {
let resultThunk
beforeEach(() => {
resultThunk = jest.fn(() => fuse._format(fuse))
resultThunk()
})
test('we should get no JSON circular', () => {
expect(resultThunk).toHaveBeenCalledTimes(1)
expect(resultThunk).not.toThrow()
})
})
})
describe('Searching using string large strings', () => {
const list = [{
text: 'pizza'
}, {
text: 'feast'
}, {
text: 'super+large+much+unique+36+very+wow+'
}]
const options = {
include: ['score', 'matches'],
shouldSort: true,
threshold: 0.5,
location: 0,
distance: 0,
maxPatternLength: 50,
minMatchCharLength: 4,
keys: [
'text'
]
}
const fuse = new Fuse(list, options)
test('finds delicious pizza', () => {
expect(fuse.search('pizza')[0].text).toBe('pizza')
})
test('finds pizza when clumbsy', () => {
expect(fuse.search('pizze')[0].text).toBe('pizza')
})
test('finds no matches when string is exactly 31 characters', () => {
expect(fuse.search('this-string-is-exactly-31-chars')).toStrictEqual([])
})
test('finds no matches when string is exactly 32 characters', () => {
expect(fuse.search('this-string-is-exactly-32-chars-')).toStrictEqual([])
})
test('finds no matches when string is larger than 32 characters', () => {
expect(fuse.search('this-string-is-more-than-32-chars')).toStrictEqual([])
})
test('should find one match that is larger than 32 characters', () => {
expect(fuse.search('super+large+much+unique+36+very+wow+')[0].text).toBe('super+large+much+unique+36+very+wow+')
})
})