Commit 6419c9a5 authored by Randall Leeds's avatar Randall Leeds

Merge pull request #1896 from hypothesis/improve-viewfilter

Improve viewfilter
parents 5f01d136 b4b68c69
...@@ -365,7 +365,7 @@ class ViewFilter ...@@ -365,7 +365,7 @@ class ViewFilter
uri: uri:
autofalse: (annotation) -> return not annotation.uri? autofalse: (annotation) -> return not annotation.uri?
value: (annotation) -> return annotation.uri value: (annotation) -> return annotation.uri
match: (term, value) -> return value is term match: (term, value) -> return value.indexOf(term) > -1
user: user:
autofalse: (annotation) -> return not annotation.user? autofalse: (annotation) -> return not annotation.user?
value: (annotation) -> return annotation.user value: (annotation) -> return annotation.user
...@@ -373,9 +373,8 @@ class ViewFilter ...@@ -373,9 +373,8 @@ class ViewFilter
any: any:
fields: ['quote', 'text', 'tag', 'user'] fields: ['quote', 'text', 'tag', 'user']
this.$inject = ['searchfilter','stringHelpers'] this.$inject = ['stringHelpers']
constructor: (searchfilter, stringHelpers) -> constructor: (stringHelpers) ->
@searchfilter = searchfilter
@_normalize = (e) -> @_normalize = (e) ->
if typeof e is 'string' if typeof e is 'string'
...@@ -399,10 +398,10 @@ class ViewFilter ...@@ -399,10 +398,10 @@ class ViewFilter
_arrayMatches: (filter, value, match) -> _arrayMatches: (filter, value, match) ->
matches = true matches = true
# Make copy for filtering # Make copy for filtering
copy = value.slice() copy = filter.terms.slice()
copy = copy.filter (e) -> copy = copy.filter (e) ->
match filter.terms, e match value, e
if (filter.operator is 'and' and copy.length < filter.terms.length) or if (filter.operator is 'and' and copy.length < filter.terms.length) or
(filter.operator is 'or' and not copy.length) (filter.operator is 'or' and not copy.length)
...@@ -436,11 +435,7 @@ class ViewFilter ...@@ -436,11 +435,7 @@ class ViewFilter
# value: a function to extract to facet value for the annotation. # value: a function to extract to facet value for the annotation.
# match: a function to check if the extracted value matches with the facet value # match: a function to check if the extracted value matches with the facet value
# #
# Returns a two-element list: # Returns the matched annotation IDs list,
# [
# matched annotation IDs list,
# the faceted filters
# ]
filter: (annotations, filters) -> filter: (annotations, filters) ->
limit = Math.min((filters.result?.terms or [])...) limit = Math.min((filters.result?.terms or [])...)
count = 0 count = 0
......
assert = chai.assert
sinon.assert.expose assert, prefix: null
poem =
tiger: 'Tiger! Tiger! burning bright
In the forest of the night
What immortal hand or eye
Could frame thy fearful symmetry?'
raven: 'Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore—
While I nodded, nearly napping, suddenly there came a tapping,
As of some one gently rapping, rapping at my chamber door.
“’Tis some visitor,” I muttered, “tapping at my chamber door—
Only this and nothing more.”'
describe 'h', ->
sandbox = null
beforeEach module('h')
beforeEach module ($provide) ->
sandbox = sinon.sandbox.create()
return
afterEach ->
sandbox.restore()
describe 'viewFilter service', ->
viewFilter = null
stringHelpers = null
beforeEach inject (_stringHelpers_, _viewFilter_) ->
stringHelpers = _stringHelpers_
viewFilter = _viewFilter_
describe 'filter', ->
it 'normalizes the filter terms', ->
stringHelpers.uniFold = sandbox.spy()
filters =
text:
terms: ['Tiger']
operator: 'and'
viewFilter.filter [], filters
assert.calledWith stringHelpers.uniFold, 'tiger'
describe 'filter operators', ->
annotations = null
beforeEach ->
annotations = [
{id: 1, text: poem.tiger},
{id: 2, text: poem.raven}
]
it 'all terms must match for "and" operator', ->
filters =
text:
terms: ['Tiger', 'burning', 'bright']
operator: 'and'
result = viewFilter.filter annotations, filters
assert.equal result.length, 1
assert.equal result[0], 1
it 'only one term must match for "or" operator', ->
filters =
text:
terms: ['Tiger', 'quaint']
operator: 'or'
result = viewFilter.filter annotations, filters
assert.equal result.length, 2
describe 'checkers', ->
describe 'autofalse', ->
it 'consider auto false function', ->
viewFilter.checkers =
test:
autofalse: sandbox.stub().returns(true)
value: (annotation) -> return annotation.test
match: (term, value) -> return value.indexOf(term) > -1
filters =
test:
terms: ['Tiger']
operator: 'and'
annotations = [{id: 1, test: poem.tiger}]
result = viewFilter.filter annotations, filters
assert.called viewFilter.checkers.test.autofalse
assert.equal result.length, 0
it 'uses the value function to extract data from the annotation', ->
viewFilter.checkers =
test:
autofalse: (annotation) -> return false
value: sandbox.stub().returns('test')
match: (term, value) -> return value.indexOf(term) > -1
filters =
test:
terms: ['test']
operator: 'and'
annotations = [{id: 1, test: poem.tiger}]
result = viewFilter.filter annotations, filters
assert.called viewFilter.checkers.test.value
assert.equal result.length, 1
it 'the match function determines the matching', ->
viewFilter.checkers =
test:
autofalse: (annotation) -> return false
value: (annotation) -> return annotation.test
match: sandbox.stub().returns(false)
filters =
test:
terms: ['Tiger']
operator: 'and'
annotations = [{id: 1, test: poem.tiger}]
result = viewFilter.filter annotations, filters
assert.called viewFilter.checkers.test.match
assert.equal result.length, 0
viewFilter.checkers.test.match.returns(true)
result = viewFilter.filter annotations, filters
assert.called viewFilter.checkers.test.match
assert.equal result.length, 1
describe 'any field', ->
it 'finds matches across many fields', ->
annotation1 = {id: 1, text: poem.tiger}
annotation2 = {id: 2, user: poem.tiger}
annotation3 = {id: 3, tags: ['Tiger']}
annotations = [annotation1, annotation2, annotation3]
filters =
any:
terms: ['Tiger']
operator: 'and'
result = viewFilter.filter annotations, filters
assert.equal result.length, 3
it 'can find terms across different fields', ->
annotation =
id:1
text: poem.tiger
target: [
selector: [{
"type": "TextQuoteSelector",
"exact": "The Tiger by William Blake",
}]
user: "acct:poe@edgar.com"
tags: ["poem", "Blake", "Tiger"]
]
filters =
any:
terms: ['burning', 'William', 'poem', 'bright']
operator: 'and'
result = viewFilter.filter [annotation], filters
assert.equal result.length, 1
assert.equal result[0], 1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment