builder_test.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. suite('lunr.Builder', function () {
  2. suite('#add', function () {
  3. setup(function () {
  4. this.builder = new lunr.Builder
  5. })
  6. test('field contains terms that clash with object prototype', function () {
  7. this.builder.field('title')
  8. this.builder.add({ id: 'id', title: 'constructor'})
  9. assert.deepProperty(this.builder.invertedIndex, 'constructor.title.id')
  10. assert.deepEqual(this.builder.invertedIndex.constructor.title.id, {})
  11. assert.equal(this.builder.fieldTermFrequencies['title/id'].constructor, 1)
  12. })
  13. test('field name clashes with object prototype', function () {
  14. this.builder.field('constructor')
  15. this.builder.add({ id: 'id', constructor: 'constructor'})
  16. assert.deepProperty(this.builder.invertedIndex, 'constructor.constructor.id')
  17. assert.deepEqual(this.builder.invertedIndex.constructor.constructor.id, {})
  18. })
  19. test('document ref clashes with object prototype', function () {
  20. this.builder.field('title')
  21. this.builder.add({ id: 'constructor', title: 'word'})
  22. assert.deepProperty(this.builder.invertedIndex, 'word.title.constructor')
  23. assert.deepEqual(this.builder.invertedIndex.word.title.constructor, {})
  24. })
  25. test('token metadata clashes with object prototype', function () {
  26. var pipelineFunction = function (t) {
  27. t.metadata['constructor'] = 'foo'
  28. return t
  29. }
  30. lunr.Pipeline.registerFunction(pipelineFunction, 'test')
  31. this.builder.pipeline.add(pipelineFunction)
  32. // the registeredFunctions object is global, this is to prevent
  33. // polluting any other tests.
  34. delete lunr.Pipeline.registeredFunctions.test
  35. this.builder.metadataWhitelist.push('constructor')
  36. this.builder.field('title')
  37. this.builder.add({ id: 'id', title: 'word'})
  38. assert.deepProperty(this.builder.invertedIndex, 'word.title.id.constructor')
  39. assert.deepEqual(this.builder.invertedIndex.word.title.id.constructor, ['foo'])
  40. })
  41. test('extracting nested properties from a document', function () {
  42. var extractor = function (d) { return d.person.name }
  43. this.builder.field('name', {
  44. extractor: extractor
  45. })
  46. this.builder.add({
  47. id: 'id',
  48. person: {
  49. name: 'bob'
  50. }
  51. })
  52. assert.deepProperty(this.builder.invertedIndex, 'bob.name.id')
  53. })
  54. })
  55. suite('#field', function () {
  56. test('defining fields to index', function () {
  57. var builder = new lunr.Builder
  58. builder.field('foo')
  59. assert.property(builder._fields, 'foo')
  60. })
  61. test('field with illegal characters', function () {
  62. var builder = new lunr.Builder
  63. assert.throws(function () {
  64. builder.field('foo/bar')
  65. })
  66. })
  67. })
  68. suite('#ref', function () {
  69. test('default reference', function () {
  70. var builder = new lunr.Builder
  71. assert.equal('id', builder._ref)
  72. })
  73. test('defining a reference field', function () {
  74. var builder = new lunr.Builder
  75. builder.ref('foo')
  76. assert.equal('foo', builder._ref)
  77. })
  78. })
  79. suite('#b', function () {
  80. test('default value', function () {
  81. var builder = new lunr.Builder
  82. assert.equal(0.75, builder._b)
  83. })
  84. test('values less than zero', function () {
  85. var builder = new lunr.Builder
  86. builder.b(-1)
  87. assert.equal(0, builder._b)
  88. })
  89. test('values higher than one', function () {
  90. var builder = new lunr.Builder
  91. builder.b(1.5)
  92. assert.equal(1, builder._b)
  93. })
  94. test('value within range', function () {
  95. var builder = new lunr.Builder
  96. builder.b(0.5)
  97. assert.equal(0.5, builder._b)
  98. })
  99. })
  100. suite('#k1', function () {
  101. test('default value', function () {
  102. var builder = new lunr.Builder
  103. assert.equal(1.2, builder._k1)
  104. })
  105. test('values less than zero', function () {
  106. var builder = new lunr.Builder
  107. builder.k1(1.6)
  108. assert.equal(1.6, builder._k1)
  109. })
  110. })
  111. suite('#use', function () {
  112. setup(function () {
  113. this.builder = new lunr.Builder
  114. })
  115. test('calls plugin function', function () {
  116. var wasCalled = false,
  117. plugin = function () { wasCalled = true }
  118. this.builder.use(plugin)
  119. assert.isTrue(wasCalled)
  120. })
  121. test('sets context to the builder instance', function () {
  122. var context = null,
  123. plugin = function () { context = this }
  124. this.builder.use(plugin)
  125. assert.equal(context, this.builder)
  126. })
  127. test('passes builder as first argument', function () {
  128. var arg = null,
  129. plugin = function (a) { arg = a }
  130. this.builder.use(plugin)
  131. assert.equal(arg, this.builder)
  132. })
  133. test('forwards arguments to the plugin', function () {
  134. var args = null,
  135. plugin = function () { args = [].slice.call(arguments) }
  136. this.builder.use(plugin, 1, 2, 3)
  137. assert.deepEqual(args, [this.builder, 1, 2, 3])
  138. })
  139. })
  140. suite('#build', function () {
  141. setup(function () {
  142. var builder = new lunr.Builder,
  143. doc = { id: 'id', title: 'test', body: 'missing' }
  144. builder.ref('id')
  145. builder.field('title')
  146. builder.add(doc)
  147. builder.build()
  148. this.builder = builder
  149. })
  150. test('adds tokens to invertedIndex', function () {
  151. assert.deepProperty(this.builder.invertedIndex, 'test.title.id')
  152. })
  153. test('builds a vector space of the document fields', function () {
  154. assert.property(this.builder.fieldVectors, 'title/id')
  155. assert.instanceOf(this.builder.fieldVectors['title/id'], lunr.Vector)
  156. })
  157. test('skips fields not defined for indexing', function () {
  158. assert.notProperty(this.builder.invertedIndex, 'missing')
  159. })
  160. test('builds a token set for the corpus', function () {
  161. var needle = lunr.TokenSet.fromString('test')
  162. assert.include(this.builder.tokenSet.intersect(needle).toArray(), 'test')
  163. })
  164. test('calculates document count', function () {
  165. assert.equal(1, this.builder.documentCount)
  166. })
  167. test('calculates average field length', function () {
  168. assert.equal(1, this.builder.averageFieldLength['title'])
  169. })
  170. test('index returned', function () {
  171. var builder = new lunr.Builder,
  172. doc = { id: 'id', title: 'test', body: 'missing' }
  173. builder.ref('id')
  174. builder.field('title')
  175. builder.add(doc)
  176. assert.instanceOf(builder.build(), lunr.Index)
  177. })
  178. })
  179. })